1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -O2 -S -mattr=avx < %s | FileCheck %s 3; RUN: opt -passes='default<O2>' -S -mattr=avx < %s | FileCheck %s 4 5target triple = "x86_64--" 6target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 7 8define i32 @ext_ext_or_reduction_v4i32(<4 x i32> %x, <4 x i32> %y) { 9; CHECK-LABEL: @ext_ext_or_reduction_v4i32( 10; CHECK-NEXT: [[Z:%.*]] = and <4 x i32> [[Y:%.*]], [[X:%.*]] 11; CHECK-NEXT: [[TMP1:%.*]] = call i32 @llvm.experimental.vector.reduce.or.v4i32(<4 x i32> [[Z]]) 12; CHECK-NEXT: ret i32 [[TMP1]] 13; 14 %z = and <4 x i32> %x, %y 15 %z0 = extractelement <4 x i32> %z, i32 0 16 %z1 = extractelement <4 x i32> %z, i32 1 17 %z01 = or i32 %z0, %z1 18 %z2 = extractelement <4 x i32> %z, i32 2 19 %z012 = or i32 %z01, %z2 20 %z3 = extractelement <4 x i32> %z, i32 3 21 %z0123 = or i32 %z3, %z012 22 ret i32 %z0123 23} 24 25define i32 @ext_ext_partial_add_reduction_v4i32(<4 x i32> %x) { 26; CHECK-LABEL: @ext_ext_partial_add_reduction_v4i32( 27; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 28; CHECK-NEXT: [[TMP2:%.*]] = add <4 x i32> [[TMP1]], [[X]] 29; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> undef, <4 x i32> <i32 2, i32 undef, i32 undef, i32 undef> 30; CHECK-NEXT: [[TMP4:%.*]] = add <4 x i32> [[TMP2]], [[TMP3]] 31; CHECK-NEXT: [[TMP5:%.*]] = extractelement <4 x i32> [[TMP4]], i64 0 32; CHECK-NEXT: ret i32 [[TMP5]] 33; 34 %x0 = extractelement <4 x i32> %x, i32 0 35 %x1 = extractelement <4 x i32> %x, i32 1 36 %x10 = add i32 %x1, %x0 37 %x2 = extractelement <4 x i32> %x, i32 2 38 %x210 = add i32 %x2, %x10 39 ret i32 %x210 40} 41 42define i32 @ext_ext_partial_add_reduction_and_extra_add_v4i32(<4 x i32> %x, <4 x i32> %y) { 43; CHECK-LABEL: @ext_ext_partial_add_reduction_and_extra_add_v4i32( 44; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[Y:%.*]], <4 x i32> undef, <4 x i32> <i32 1, i32 undef, i32 undef, i32 undef> 45; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> undef, <4 x i32> <i32 2, i32 undef, i32 undef, i32 undef> 46; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i32> [[X:%.*]], <4 x i32> undef, <4 x i32> <i32 2, i32 undef, i32 undef, i32 undef> 47; CHECK-NEXT: [[TMP4:%.*]] = add <4 x i32> [[TMP3]], [[Y]] 48; CHECK-NEXT: [[TMP5:%.*]] = add <4 x i32> [[TMP4]], [[TMP1]] 49; CHECK-NEXT: [[TMP6:%.*]] = add <4 x i32> [[TMP5]], [[TMP2]] 50; CHECK-NEXT: [[TMP7:%.*]] = extractelement <4 x i32> [[TMP6]], i32 0 51; CHECK-NEXT: ret i32 [[TMP7]] 52; 53 %y0 = extractelement <4 x i32> %y, i32 0 54 %y1 = extractelement <4 x i32> %y, i32 1 55 %y10 = add i32 %y1, %y0 56 %y2 = extractelement <4 x i32> %y, i32 2 57 %y210 = add i32 %y2, %y10 58 %x2 = extractelement <4 x i32> %x, i32 2 59 %x2y210 = add i32 %x2, %y210 60 ret i32 %x2y210 61} 62 63; PR43953 - https://bugs.llvm.org/show_bug.cgi?id=43953 64; We want to end up with a single reduction on the next 4 tests. 65 66define i32 @TestVectorsEqual(i32* noalias %Vec0, i32* noalias %Vec1, i32 %Tolerance) { 67; CHECK-LABEL: @TestVectorsEqual( 68; CHECK-NEXT: entry: 69; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[VEC0:%.*]] to <4 x i32>* 70; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 71; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32* [[VEC1:%.*]] to <4 x i32>* 72; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, <4 x i32>* [[TMP2]], align 4 73; CHECK-NEXT: [[TMP4:%.*]] = sub nsw <4 x i32> [[TMP1]], [[TMP3]] 74; CHECK-NEXT: [[TMP5:%.*]] = icmp slt <4 x i32> [[TMP4]], zeroinitializer 75; CHECK-NEXT: [[TMP6:%.*]] = sub nsw <4 x i32> zeroinitializer, [[TMP4]] 76; CHECK-NEXT: [[TMP7:%.*]] = select <4 x i1> [[TMP5]], <4 x i32> [[TMP6]], <4 x i32> [[TMP4]] 77; CHECK-NEXT: [[TMP8:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP7]]) 78; CHECK-NEXT: [[CMP5:%.*]] = icmp sle i32 [[TMP8]], [[TOLERANCE:%.*]] 79; CHECK-NEXT: [[COND6:%.*]] = zext i1 [[CMP5]] to i32 80; CHECK-NEXT: ret i32 [[COND6]] 81; 82entry: 83 br label %for.cond 84 85for.cond: 86 %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ] 87 %Component.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 88 %cmp = icmp slt i32 %Component.0, 4 89 br i1 %cmp, label %for.body, label %for.cond.cleanup 90 91for.cond.cleanup: 92 br label %for.end 93 94for.body: 95 %idxprom = sext i32 %Component.0 to i64 96 %arrayidx = getelementptr inbounds i32, i32* %Vec0, i64 %idxprom 97 %0 = load i32, i32* %arrayidx, align 4 98 %idxprom1 = sext i32 %Component.0 to i64 99 %arrayidx2 = getelementptr inbounds i32, i32* %Vec1, i64 %idxprom1 100 %1 = load i32, i32* %arrayidx2, align 4 101 %sub = sub nsw i32 %0, %1 102 %cmp3 = icmp sge i32 %sub, 0 103 br i1 %cmp3, label %cond.true, label %cond.false 104 105cond.true: 106 br label %cond.end 107 108cond.false: 109 %sub4 = sub nsw i32 0, %sub 110 br label %cond.end 111 112cond.end: 113 %cond = phi i32 [ %sub, %cond.true ], [ %sub4, %cond.false ] 114 %add = add nsw i32 %sum.0, %cond 115 br label %for.inc 116 117for.inc: 118 %inc = add nsw i32 %Component.0, 1 119 br label %for.cond 120 121for.end: 122 %cmp5 = icmp sle i32 %sum.0, %Tolerance 123 %2 = zext i1 %cmp5 to i64 124 %cond6 = select i1 %cmp5, i32 1, i32 0 125 ret i32 %cond6 126} 127 128define i32 @TestVectorsEqual_alt(i32* noalias %Vec0, i32* noalias %Vec1, i32 %Tolerance) { 129; CHECK-LABEL: @TestVectorsEqual_alt( 130; CHECK-NEXT: entry: 131; CHECK-NEXT: [[TMP0:%.*]] = bitcast i32* [[VEC0:%.*]] to <4 x i32>* 132; CHECK-NEXT: [[TMP1:%.*]] = load <4 x i32>, <4 x i32>* [[TMP0]], align 4 133; CHECK-NEXT: [[TMP2:%.*]] = bitcast i32* [[VEC1:%.*]] to <4 x i32>* 134; CHECK-NEXT: [[TMP3:%.*]] = load <4 x i32>, <4 x i32>* [[TMP2]], align 4 135; CHECK-NEXT: [[TMP4:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP1]]) 136; CHECK-NEXT: [[TMP5:%.*]] = call i32 @llvm.experimental.vector.reduce.add.v4i32(<4 x i32> [[TMP3]]) 137; CHECK-NEXT: [[ADD_3:%.*]] = sub i32 [[TMP4]], [[TMP5]] 138; CHECK-NEXT: [[CMP3:%.*]] = icmp ule i32 [[ADD_3]], [[TOLERANCE:%.*]] 139; CHECK-NEXT: [[COND:%.*]] = zext i1 [[CMP3]] to i32 140; CHECK-NEXT: ret i32 [[COND]] 141; 142entry: 143 br label %for.cond 144 145for.cond: 146 %sum.0 = phi i32 [ 0, %entry ], [ %add, %for.inc ] 147 %Component.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 148 %cmp = icmp slt i32 %Component.0, 4 149 br i1 %cmp, label %for.body, label %for.cond.cleanup 150 151for.cond.cleanup: 152 br label %for.end 153 154for.body: 155 %idxprom = sext i32 %Component.0 to i64 156 %arrayidx = getelementptr inbounds i32, i32* %Vec0, i64 %idxprom 157 %0 = load i32, i32* %arrayidx, align 4 158 %idxprom1 = sext i32 %Component.0 to i64 159 %arrayidx2 = getelementptr inbounds i32, i32* %Vec1, i64 %idxprom1 160 %1 = load i32, i32* %arrayidx2, align 4 161 %sub = sub i32 %0, %1 162 %add = add i32 %sum.0, %sub 163 br label %for.inc 164 165for.inc: 166 %inc = add nsw i32 %Component.0, 1 167 br label %for.cond 168 169for.end: 170 %cmp3 = icmp ule i32 %sum.0, %Tolerance 171 %2 = zext i1 %cmp3 to i64 172 %cond = select i1 %cmp3, i32 1, i32 0 173 ret i32 %cond 174} 175 176define i32 @TestVectorsEqualFP(float* noalias %Vec0, float* noalias %Vec1, float %Tolerance) { 177; CHECK-LABEL: @TestVectorsEqualFP( 178; CHECK-NEXT: entry: 179; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[VEC0:%.*]] to <4 x float>* 180; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4 181; CHECK-NEXT: [[TMP2:%.*]] = bitcast float* [[VEC1:%.*]] to <4 x float>* 182; CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* [[TMP2]], align 4 183; CHECK-NEXT: [[TMP4:%.*]] = fsub fast <4 x float> [[TMP1]], [[TMP3]] 184; CHECK-NEXT: [[TMP5:%.*]] = call fast <4 x float> @llvm.fabs.v4f32(<4 x float> [[TMP4]]) 185; CHECK-NEXT: [[TMP6:%.*]] = call fast float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float 0.000000e+00, <4 x float> [[TMP5]]) 186; CHECK-NEXT: [[CMP4:%.*]] = fcmp fast ole float [[TMP6]], [[TOLERANCE:%.*]] 187; CHECK-NEXT: [[COND5:%.*]] = zext i1 [[CMP4]] to i32 188; CHECK-NEXT: ret i32 [[COND5]] 189; 190entry: 191 br label %for.cond 192 193for.cond: 194 %sum.0 = phi float [ 0.000000e+00, %entry ], [ %add, %for.inc ] 195 %Component.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 196 %cmp = icmp slt i32 %Component.0, 4 197 br i1 %cmp, label %for.body, label %for.cond.cleanup 198 199for.cond.cleanup: 200 br label %for.end 201 202for.body: 203 %idxprom = sext i32 %Component.0 to i64 204 %arrayidx = getelementptr inbounds float, float* %Vec0, i64 %idxprom 205 %0 = load float, float* %arrayidx, align 4 206 %idxprom1 = sext i32 %Component.0 to i64 207 %arrayidx2 = getelementptr inbounds float, float* %Vec1, i64 %idxprom1 208 %1 = load float, float* %arrayidx2, align 4 209 %sub = fsub fast float %0, %1 210 %cmp3 = fcmp fast oge float %sub, 0.000000e+00 211 br i1 %cmp3, label %cond.true, label %cond.false 212 213cond.true: 214 br label %cond.end 215 216cond.false: 217 %fneg = fneg fast float %sub 218 br label %cond.end 219 220cond.end: 221 %cond = phi fast float [ %sub, %cond.true ], [ %fneg, %cond.false ] 222 %add = fadd fast float %sum.0, %cond 223 br label %for.inc 224 225for.inc: 226 %inc = add nsw i32 %Component.0, 1 227 br label %for.cond 228 229for.end: 230 %cmp4 = fcmp fast ole float %sum.0, %Tolerance 231 %2 = zext i1 %cmp4 to i64 232 %cond5 = select i1 %cmp4, i32 1, i32 0 233 ret i32 %cond5 234} 235 236define i32 @TestVectorsEqualFP_alt(float* noalias %Vec0, float* noalias %Vec1, float %Tolerance) { 237; CHECK-LABEL: @TestVectorsEqualFP_alt( 238; CHECK-NEXT: entry: 239; CHECK-NEXT: [[TMP0:%.*]] = bitcast float* [[VEC0:%.*]] to <4 x float>* 240; CHECK-NEXT: [[TMP1:%.*]] = load <4 x float>, <4 x float>* [[TMP0]], align 4 241; CHECK-NEXT: [[TMP2:%.*]] = bitcast float* [[VEC1:%.*]] to <4 x float>* 242; CHECK-NEXT: [[TMP3:%.*]] = load <4 x float>, <4 x float>* [[TMP2]], align 4 243; CHECK-NEXT: [[TMP4:%.*]] = call fast float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float 0.000000e+00, <4 x float> [[TMP1]]) 244; CHECK-NEXT: [[TMP5:%.*]] = call fast float @llvm.experimental.vector.reduce.v2.fadd.f32.v4f32(float 0.000000e+00, <4 x float> [[TMP3]]) 245; CHECK-NEXT: [[ADD_3:%.*]] = fsub fast float [[TMP4]], [[TMP5]] 246; CHECK-NEXT: [[CMP3:%.*]] = fcmp fast ole float [[ADD_3]], [[TOLERANCE:%.*]] 247; CHECK-NEXT: [[COND:%.*]] = zext i1 [[CMP3]] to i32 248; CHECK-NEXT: ret i32 [[COND]] 249; 250entry: 251 br label %for.cond 252 253for.cond: 254 %sum.0 = phi float [ 0.000000e+00, %entry ], [ %add, %for.inc ] 255 %Component.0 = phi i32 [ 0, %entry ], [ %inc, %for.inc ] 256 %cmp = icmp slt i32 %Component.0, 4 257 br i1 %cmp, label %for.body, label %for.cond.cleanup 258 259for.cond.cleanup: 260 br label %for.end 261 262for.body: 263 %idxprom = sext i32 %Component.0 to i64 264 %arrayidx = getelementptr inbounds float, float* %Vec0, i64 %idxprom 265 %0 = load float, float* %arrayidx, align 4 266 %idxprom1 = sext i32 %Component.0 to i64 267 %arrayidx2 = getelementptr inbounds float, float* %Vec1, i64 %idxprom1 268 %1 = load float, float* %arrayidx2, align 4 269 %sub = fsub fast float %0, %1 270 %add = fadd fast float %sum.0, %sub 271 br label %for.inc 272 273for.inc: 274 %inc = add nsw i32 %Component.0, 1 275 br label %for.cond 276 277for.end: 278 %cmp3 = fcmp fast ole float %sum.0, %Tolerance 279 %2 = zext i1 %cmp3 to i64 280 %cond = select i1 %cmp3, i32 1, i32 0 281 ret i32 %cond 282} 283