brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.4 KiB · bdc09ed Raw
554 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: %if x86-registered-target %{ opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-apple-macosx10.9.0 | FileCheck %s --check-prefixes=CHECK-X86 %}3; RUN: %if aarch64-registered-target %{ opt < %s -passes=slp-vectorizer -S -mtriple=aarch64-unknown-linux-gnu | FileCheck %s --check-prefixes=CHECK-AARCH64 %}4 5@A = common global [2000 x double] zeroinitializer, align 166@B = common global [2000 x double] zeroinitializer, align 167@C = common global [2000 x float] zeroinitializer, align 168@D = common global [2000 x float] zeroinitializer, align 169 10; Function Attrs: nounwind ssp uwtable11define void @foo_3double(i32 %u) {12; CHECK-LABEL: @foo_3double(13; CHECK-NEXT:  entry:14; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 415; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 416; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[U]], 317; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i6418; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]19; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]20; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 821; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 822; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]23; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 824; CHECK-NEXT:    [[ADD24:%.*]] = add nsw i32 [[MUL]], 225; CHECK-NEXT:    [[IDXPROM25:%.*]] = sext i32 [[ADD24]] to i6426; CHECK-NEXT:    [[ARRAYIDX26:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM25]]27; CHECK-NEXT:    [[TMP3:%.*]] = load double, ptr [[ARRAYIDX26]], align 828; CHECK-NEXT:    [[ARRAYIDX30:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM25]]29; CHECK-NEXT:    [[TMP4:%.*]] = load double, ptr [[ARRAYIDX30]], align 830; CHECK-NEXT:    [[ADD31:%.*]] = fadd double [[TMP3]], [[TMP4]]31; CHECK-NEXT:    store double [[ADD31]], ptr [[ARRAYIDX26]], align 832; CHECK-NEXT:    ret void33;34entry:35  %u.addr = alloca i32, align 436  store i32 %u, ptr %u.addr, align 437  %mul = mul nsw i32 %u, 338  %idxprom = sext i32 %mul to i6439  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom40  %0 = load double, ptr %arrayidx, align 841  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom42  %1 = load double, ptr %arrayidx4, align 843  %add5 = fadd double %0, %144  store double %add5, ptr %arrayidx, align 845  %add11 = add nsw i32 %mul, 146  %idxprom12 = sext i32 %add11 to i6447  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom1248  %2 = load double, ptr %arrayidx13, align 849  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom1250  %3 = load double, ptr %arrayidx17, align 851  %add18 = fadd double %2, %352  store double %add18, ptr %arrayidx13, align 853  %add24 = add nsw i32 %mul, 254  %idxprom25 = sext i32 %add24 to i6455  %arrayidx26 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom2556  %4 = load double, ptr %arrayidx26, align 857  %arrayidx30 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom2558  %5 = load double, ptr %arrayidx30, align 859  %add31 = fadd double %4, %560  store double %add31, ptr %arrayidx26, align 861  ret void62}63 64; SCEV should be able to tell that accesses A[C1 + C2*i], A[C1 + C2*i], ...65; A[C1 + C2*i] are consecutive, if C2 is a power of 2, and C2 > C1 > 0.66; Thus, the following code should be vectorized.67; Function Attrs: nounwind ssp uwtable68define void @foo_2double(i32 %u) {69; CHECK-LABEL: @foo_2double(70; CHECK-NEXT:  entry:71; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 472; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 473; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[U]], 274; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i6475; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]76; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]77; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 878; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 879; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]80; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 881; CHECK-NEXT:    ret void82;83entry:84  %u.addr = alloca i32, align 485  store i32 %u, ptr %u.addr, align 486  %mul = mul nsw i32 %u, 287  %idxprom = sext i32 %mul to i6488  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom89  %0 = load double, ptr %arrayidx, align 890  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom91  %1 = load double, ptr %arrayidx4, align 892  %add5 = fadd double %0, %193  store double %add5, ptr %arrayidx, align 894  %add11 = add nsw i32 %mul, 195  %idxprom12 = sext i32 %add11 to i6496  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom1297  %2 = load double, ptr %arrayidx13, align 898  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom1299  %3 = load double, ptr %arrayidx17, align 8100  %add18 = fadd double %2, %3101  store double %add18, ptr %arrayidx13, align 8102  ret void103}104 105; Similar to the previous test, but with different datatype.106; Function Attrs: nounwind ssp uwtable107define void @foo_4float(i32 %u) {108; CHECK-LABEL: @foo_4float(109; CHECK-NEXT:  entry:110; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4111; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4112; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[U]], 4113; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i64114; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 [[IDXPROM]]115; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 [[IDXPROM]]116; CHECK-NEXT:    [[TMP0:%.*]] = load <4 x float>, ptr [[ARRAYIDX]], align 4117; CHECK-NEXT:    [[TMP1:%.*]] = load <4 x float>, ptr [[ARRAYIDX4]], align 4118; CHECK-NEXT:    [[TMP2:%.*]] = fadd <4 x float> [[TMP0]], [[TMP1]]119; CHECK-NEXT:    store <4 x float> [[TMP2]], ptr [[ARRAYIDX]], align 4120; CHECK-NEXT:    ret void121;122entry:123  %u.addr = alloca i32, align 4124  store i32 %u, ptr %u.addr, align 4125  %mul = mul nsw i32 %u, 4126  %idxprom = sext i32 %mul to i64127  %arrayidx = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom128  %0 = load float, ptr %arrayidx, align 4129  %arrayidx4 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom130  %1 = load float, ptr %arrayidx4, align 4131  %add5 = fadd float %0, %1132  store float %add5, ptr %arrayidx, align 4133  %add11 = add nsw i32 %mul, 1134  %idxprom12 = sext i32 %add11 to i64135  %arrayidx13 = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom12136  %2 = load float, ptr %arrayidx13, align 4137  %arrayidx17 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom12138  %3 = load float, ptr %arrayidx17, align 4139  %add18 = fadd float %2, %3140  store float %add18, ptr %arrayidx13, align 4141  %add24 = add nsw i32 %mul, 2142  %idxprom25 = sext i32 %add24 to i64143  %arrayidx26 = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom25144  %4 = load float, ptr %arrayidx26, align 4145  %arrayidx30 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom25146  %5 = load float, ptr %arrayidx30, align 4147  %add31 = fadd float %4, %5148  store float %add31, ptr %arrayidx26, align 4149  %add37 = add nsw i32 %mul, 3150  %idxprom38 = sext i32 %add37 to i64151  %arrayidx39 = getelementptr inbounds [2000 x float], ptr @C, i32 0, i64 %idxprom38152  %6 = load float, ptr %arrayidx39, align 4153  %arrayidx43 = getelementptr inbounds [2000 x float], ptr @D, i32 0, i64 %idxprom38154  %7 = load float, ptr %arrayidx43, align 4155  %add44 = fadd float %6, %7156  store float %add44, ptr %arrayidx39, align 4157  ret void158}159 160; Similar to the previous tests, but now we are dealing with AddRec SCEV.161; Function Attrs: nounwind ssp uwtable162define i32 @foo_loop(ptr %A, i32 %n) {163; CHECK-LABEL: @foo_loop(164; CHECK-NEXT:  entry:165; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8166; CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4167; CHECK-NEXT:    [[SUM:%.*]] = alloca double, align 8168; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4169; CHECK-NEXT:    store ptr [[A:%.*]], ptr [[A_ADDR]], align 8170; CHECK-NEXT:    store i32 [[N:%.*]], ptr [[N_ADDR]], align 4171; CHECK-NEXT:    store double 0.000000e+00, ptr [[SUM]], align 8172; CHECK-NEXT:    store i32 0, ptr [[I]], align 4173; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 0, [[N]]174; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]175; CHECK:       for.body.lr.ph:176; CHECK-NEXT:    br label [[FOR_BODY:%.*]]177; CHECK:       for.body:178; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]179; CHECK-NEXT:    [[TMP1:%.*]] = phi double [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[ADD7:%.*]], [[FOR_BODY]] ]180; CHECK-NEXT:    [[MUL:%.*]] = mul nsw i32 [[TMP0]], 2181; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[MUL]] to i64182; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IDXPROM]]183; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8184; CHECK-NEXT:    [[TMP3:%.*]] = fmul <2 x double> <double 7.000000e+00, double 7.000000e+00>, [[TMP2]]185; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[TMP3]], i32 0186; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x double> [[TMP3]], i32 1187; CHECK-NEXT:    [[ADD6:%.*]] = fadd double [[TMP4]], [[TMP5]]188; CHECK-NEXT:    [[ADD7]] = fadd double [[TMP1]], [[ADD6]]189; CHECK-NEXT:    store double [[ADD7]], ptr [[SUM]], align 8190; CHECK-NEXT:    [[INC]] = add nsw i32 [[TMP0]], 1191; CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4192; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N]]193; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]194; CHECK:       for.cond.for.end_crit_edge:195; CHECK-NEXT:    [[SPLIT:%.*]] = phi double [ [[ADD7]], [[FOR_BODY]] ]196; CHECK-NEXT:    br label [[FOR_END]]197; CHECK:       for.end:198; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi double [ [[SPLIT]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]199; CHECK-NEXT:    [[CONV:%.*]] = fptosi double [[DOTLCSSA]] to i32200; CHECK-NEXT:    ret i32 [[CONV]]201;202entry:203  %A.addr = alloca ptr, align 8204  %n.addr = alloca i32, align 4205  %sum = alloca double, align 8206  %i = alloca i32, align 4207  store ptr %A, ptr %A.addr, align 8208  store i32 %n, ptr %n.addr, align 4209  store double 0.000000e+00, ptr %sum, align 8210  store i32 0, ptr %i, align 4211  %cmp1 = icmp slt i32 0, %n212  br i1 %cmp1, label %for.body.lr.ph, label %for.end213 214for.body.lr.ph:                                   ; preds = %entry215  br label %for.body216 217for.body:                                         ; preds = %for.body.lr.ph, %for.body218  %0 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]219  %1 = phi double [ 0.000000e+00, %for.body.lr.ph ], [ %add7, %for.body ]220  %mul = mul nsw i32 %0, 2221  %idxprom = sext i32 %mul to i64222  %arrayidx = getelementptr inbounds double, ptr %A, i64 %idxprom223  %2 = load double, ptr %arrayidx, align 8224  %mul1 = fmul double 7.000000e+00, %2225  %add = add nsw i32 %mul, 1226  %idxprom3 = sext i32 %add to i64227  %arrayidx4 = getelementptr inbounds double, ptr %A, i64 %idxprom3228  %3 = load double, ptr %arrayidx4, align 8229  %mul5 = fmul double 7.000000e+00, %3230  %add6 = fadd double %mul1, %mul5231  %add7 = fadd double %1, %add6232  store double %add7, ptr %sum, align 8233  %inc = add nsw i32 %0, 1234  store i32 %inc, ptr %i, align 4235  %cmp = icmp slt i32 %inc, %n236  br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge237 238for.cond.for.end_crit_edge:                       ; preds = %for.body239  %split = phi double [ %add7, %for.body ]240  br label %for.end241 242for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry243  %.lcssa = phi double [ %split, %for.cond.for.end_crit_edge ], [ 0.000000e+00, %entry ]244  %conv = fptosi double %.lcssa to i32245  ret i32 %conv246}247 248; Similar to foo_2double but with a non-power-of-2 factor and potential249; wrapping (both indices wrap or both don't in the same time)250; Function Attrs: nounwind ssp uwtable251define void @foo_2double_non_power_of_2(i32 %u) {252; CHECK-LABEL: @foo_2double_non_power_of_2(253; CHECK-NEXT:  entry:254; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4255; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4256; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[U]], 6257; CHECK-NEXT:    [[ADD6:%.*]] = add i32 [[MUL]], 6258; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[ADD6]] to i64259; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]260; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]261; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8262; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 8263; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]264; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 8265; CHECK-NEXT:    ret void266;267entry:268  %u.addr = alloca i32, align 4269  store i32 %u, ptr %u.addr, align 4270  %mul = mul i32 %u, 6271  %add6 = add i32 %mul, 6272  %idxprom = sext i32 %add6 to i64273  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom274  %0 = load double, ptr %arrayidx, align 8275  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom276  %1 = load double, ptr %arrayidx4, align 8277  %add5 = fadd double %0, %1278  store double %add5, ptr %arrayidx, align 8279  %add7 = add i32 %mul, 7280  %idxprom12 = sext i32 %add7 to i64281  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom12282  %2 = load double, ptr %arrayidx13, align 8283  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom12284  %3 = load double, ptr %arrayidx17, align 8285  %add18 = fadd double %2, %3286  store double %add18, ptr %arrayidx13, align 8287  ret void288}289 290; Similar to foo_2double_non_power_of_2 but with zext's instead of sext's291; Function Attrs: nounwind ssp uwtable292define void @foo_2double_non_power_of_2_zext(i32 %u) {293; CHECK-LABEL: @foo_2double_non_power_of_2_zext(294; CHECK-NEXT:  entry:295; CHECK-NEXT:    [[U_ADDR:%.*]] = alloca i32, align 4296; CHECK-NEXT:    store i32 [[U:%.*]], ptr [[U_ADDR]], align 4297; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[U]], 6298; CHECK-NEXT:    [[ADD6:%.*]] = add i32 [[MUL]], 6299; CHECK-NEXT:    [[IDXPROM:%.*]] = zext i32 [[ADD6]] to i64300; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 [[IDXPROM]]301; CHECK-NEXT:    [[ARRAYIDX4:%.*]] = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 [[IDXPROM]]302; CHECK-NEXT:    [[TMP0:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8303; CHECK-NEXT:    [[TMP1:%.*]] = load <2 x double>, ptr [[ARRAYIDX4]], align 8304; CHECK-NEXT:    [[TMP2:%.*]] = fadd <2 x double> [[TMP0]], [[TMP1]]305; CHECK-NEXT:    store <2 x double> [[TMP2]], ptr [[ARRAYIDX]], align 8306; CHECK-NEXT:    ret void307;308entry:309  %u.addr = alloca i32, align 4310  store i32 %u, ptr %u.addr, align 4311  %mul = mul i32 %u, 6312  %add6 = add i32 %mul, 6313  %idxprom = zext i32 %add6 to i64314  %arrayidx = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom315  %0 = load double, ptr %arrayidx, align 8316  %arrayidx4 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom317  %1 = load double, ptr %arrayidx4, align 8318  %add5 = fadd double %0, %1319  store double %add5, ptr %arrayidx, align 8320  %add7 = add i32 %mul, 7321  %idxprom12 = zext i32 %add7 to i64322  %arrayidx13 = getelementptr inbounds [2000 x double], ptr @A, i32 0, i64 %idxprom12323  %2 = load double, ptr %arrayidx13, align 8324  %arrayidx17 = getelementptr inbounds [2000 x double], ptr @B, i32 0, i64 %idxprom12325  %3 = load double, ptr %arrayidx17, align 8326  %add18 = fadd double %2, %3327  store double %add18, ptr %arrayidx13, align 8328  ret void329}330 331; Similar to foo_2double_non_power_of_2, but now we are dealing with AddRec SCEV.332; Alternatively, this is like foo_loop, but with a non-power-of-2 factor and333; potential wrapping (both indices wrap or both don't in the same time)334; Function Attrs: nounwind ssp uwtable335define i32 @foo_loop_non_power_of_2(ptr %A, i32 %n) {336; CHECK-LABEL: @foo_loop_non_power_of_2(337; CHECK-NEXT:  entry:338; CHECK-NEXT:    [[A_ADDR:%.*]] = alloca ptr, align 8339; CHECK-NEXT:    [[N_ADDR:%.*]] = alloca i32, align 4340; CHECK-NEXT:    [[SUM:%.*]] = alloca double, align 8341; CHECK-NEXT:    [[I:%.*]] = alloca i32, align 4342; CHECK-NEXT:    store ptr [[A:%.*]], ptr [[A_ADDR]], align 8343; CHECK-NEXT:    store i32 [[N:%.*]], ptr [[N_ADDR]], align 4344; CHECK-NEXT:    store double 0.000000e+00, ptr [[SUM]], align 8345; CHECK-NEXT:    store i32 0, ptr [[I]], align 4346; CHECK-NEXT:    [[CMP1:%.*]] = icmp slt i32 0, [[N]]347; CHECK-NEXT:    br i1 [[CMP1]], label [[FOR_BODY_LR_PH:%.*]], label [[FOR_END:%.*]]348; CHECK:       for.body.lr.ph:349; CHECK-NEXT:    br label [[FOR_BODY:%.*]]350; CHECK:       for.body:351; CHECK-NEXT:    [[TMP0:%.*]] = phi i32 [ 0, [[FOR_BODY_LR_PH]] ], [ [[INC:%.*]], [[FOR_BODY]] ]352; CHECK-NEXT:    [[TMP1:%.*]] = phi double [ 0.000000e+00, [[FOR_BODY_LR_PH]] ], [ [[ADD7:%.*]], [[FOR_BODY]] ]353; CHECK-NEXT:    [[MUL:%.*]] = mul i32 [[TMP0]], 12354; CHECK-NEXT:    [[ADD_5:%.*]] = add i32 [[MUL]], 5355; CHECK-NEXT:    [[IDXPROM:%.*]] = sext i32 [[ADD_5]] to i64356; CHECK-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IDXPROM]]357; CHECK-NEXT:    [[TMP2:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8358; CHECK-NEXT:    [[TMP3:%.*]] = fmul <2 x double> <double 7.000000e+00, double 7.000000e+00>, [[TMP2]]359; CHECK-NEXT:    [[TMP4:%.*]] = extractelement <2 x double> [[TMP3]], i32 0360; CHECK-NEXT:    [[TMP5:%.*]] = extractelement <2 x double> [[TMP3]], i32 1361; CHECK-NEXT:    [[ADD6:%.*]] = fadd double [[TMP4]], [[TMP5]]362; CHECK-NEXT:    [[ADD7]] = fadd double [[TMP1]], [[ADD6]]363; CHECK-NEXT:    store double [[ADD7]], ptr [[SUM]], align 8364; CHECK-NEXT:    [[INC]] = add i32 [[TMP0]], 1365; CHECK-NEXT:    store i32 [[INC]], ptr [[I]], align 4366; CHECK-NEXT:    [[CMP:%.*]] = icmp slt i32 [[INC]], [[N]]367; CHECK-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_FOR_END_CRIT_EDGE:%.*]]368; CHECK:       for.cond.for.end_crit_edge:369; CHECK-NEXT:    [[SPLIT:%.*]] = phi double [ [[ADD7]], [[FOR_BODY]] ]370; CHECK-NEXT:    br label [[FOR_END]]371; CHECK:       for.end:372; CHECK-NEXT:    [[DOTLCSSA:%.*]] = phi double [ [[SPLIT]], [[FOR_COND_FOR_END_CRIT_EDGE]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]373; CHECK-NEXT:    [[CONV:%.*]] = fptosi double [[DOTLCSSA]] to i32374; CHECK-NEXT:    ret i32 [[CONV]]375;376entry:377  %A.addr = alloca ptr, align 8378  %n.addr = alloca i32, align 4379  %sum = alloca double, align 8380  %i = alloca i32, align 4381  store ptr %A, ptr %A.addr, align 8382  store i32 %n, ptr %n.addr, align 4383  store double 0.000000e+00, ptr %sum, align 8384  store i32 0, ptr %i, align 4385  %cmp1 = icmp slt i32 0, %n386  br i1 %cmp1, label %for.body.lr.ph, label %for.end387 388for.body.lr.ph:                                   ; preds = %entry389  br label %for.body390 391for.body:                                         ; preds = %for.body.lr.ph, %for.body392  %0 = phi i32 [ 0, %for.body.lr.ph ], [ %inc, %for.body ]393  %1 = phi double [ 0.000000e+00, %for.body.lr.ph ], [ %add7, %for.body ]394  %mul = mul i32 %0, 12395  %add.5 = add i32 %mul, 5396  %idxprom = sext i32 %add.5 to i64397  %arrayidx = getelementptr inbounds double, ptr %A, i64 %idxprom398  %2 = load double, ptr %arrayidx, align 8399  %mul1 = fmul double 7.000000e+00, %2400  %add.6 = add i32 %mul, 6401  %idxprom3 = sext i32 %add.6 to i64402  %arrayidx4 = getelementptr inbounds double, ptr %A, i64 %idxprom3403  %3 = load double, ptr %arrayidx4, align 8404  %mul5 = fmul double 7.000000e+00, %3405  %add6 = fadd double %mul1, %mul5406  %add7 = fadd double %1, %add6407  store double %add7, ptr %sum, align 8408  %inc = add i32 %0, 1409  store i32 %inc, ptr %i, align 4410  %cmp = icmp slt i32 %inc, %n411  br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge412 413for.cond.for.end_crit_edge:                       ; preds = %for.body414  %split = phi double [ %add7, %for.body ]415  br label %for.end416 417for.end:                                          ; preds = %for.cond.for.end_crit_edge, %entry418  %.lcssa = phi double [ %split, %for.cond.for.end_crit_edge ], [ 0.000000e+00, %entry ]419  %conv = fptosi double %.lcssa to i32420  ret i32 %conv421}422 423; This is generated by `clang -std=c11 -Wpedantic -Wall -O3 main.c -S -o - -emit-llvm`424; with !{!"clang version 7.0.0 (trunk 337339) (llvm/trunk 337344)"} and stripping off425; the !tbaa metadata nodes to fit the rest of the test file, where `cat main.c` is:426;427;  double bar(ptr a, unsigned n) {428;    double x = 0.0;429;    double y = 0.0;430;    for (unsigned i = 0; i < n; i += 2) {431;      x += a[i];432;      y += a[i + 1];433;    }434;    return x * y;435;  }436;437; The resulting IR is similar to @foo_loop, but with zext's instead of sext's.438;439; Make sure we are able to vectorize this from now on:440;441define double @bar(ptr nocapture readonly %a, i32 %n) local_unnamed_addr {442; CHECK-X86-LABEL: @bar(443; CHECK-X86-NEXT:  entry:444; CHECK-X86-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[N:%.*]], 0445; CHECK-X86-NEXT:    br i1 [[CMP15]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]446; CHECK-X86:       for.cond.cleanup:447; CHECK-X86-NEXT:    [[TMP0:%.*]] = phi <2 x double> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[TMP5:%.*]], [[FOR_BODY]] ]448; CHECK-X86-NEXT:    [[TMP1:%.*]] = extractelement <2 x double> [[TMP0]], i32 0449; CHECK-X86-NEXT:    [[TMP2:%.*]] = extractelement <2 x double> [[TMP0]], i32 1450; CHECK-X86-NEXT:    [[MUL:%.*]] = fmul double [[TMP1]], [[TMP2]]451; CHECK-X86-NEXT:    ret double [[MUL]]452; CHECK-X86:       for.body:453; CHECK-X86-NEXT:    [[I_018:%.*]] = phi i32 [ [[ADD5:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]454; CHECK-X86-NEXT:    [[TMP3:%.*]] = phi <2 x double> [ [[TMP5]], [[FOR_BODY]] ], [ zeroinitializer, [[ENTRY]] ]455; CHECK-X86-NEXT:    [[IDXPROM:%.*]] = zext i32 [[I_018]] to i64456; CHECK-X86-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[IDXPROM]]457; CHECK-X86-NEXT:    [[TMP4:%.*]] = load <2 x double>, ptr [[ARRAYIDX]], align 8458; CHECK-X86-NEXT:    [[TMP5]] = fadd <2 x double> [[TMP3]], [[TMP4]]459; CHECK-X86-NEXT:    [[ADD5]] = add i32 [[I_018]], 2460; CHECK-X86-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD5]], [[N]]461; CHECK-X86-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP]]462;463 464; CHECK-AARCH64-LABEL: @bar(465; CHECK-AARCH64-NEXT:  entry:466; CHECK-AARCH64-NEXT:    [[CMP15:%.*]] = icmp eq i32 [[N:%.*]], 0467; CHECK-AARCH64-NEXT:    br i1 [[CMP15]], label [[FOR_COND_CLEANUP:%.*]], label [[FOR_BODY:%.*]]468; CHECK-AARCH64:       for.cond.cleanup:469; CHECK-AARCH64-NEXT:    [[X_0_LCSSA:%.*]] = phi double [ 0.000000e+00, [[ENTRY:%.*]] ], [ [[ADD:%.*]], [[FOR_BODY]] ]470; CHECK-AARCH64-NEXT:    [[Y_0_LCSSA:%.*]] = phi double [ 0.000000e+00, [[ENTRY]] ], [ [[ADD4:%.*]], [[FOR_BODY]] ]471; CHECK-AARCH64-NEXT:    [[MUL:%.*]] = fmul double [[X_0_LCSSA]], [[Y_0_LCSSA]]472; CHECK-AARCH64-NEXT:    ret double [[MUL]]473; CHECK-AARCH64:       for.body:474; CHECK-AARCH64-NEXT:    [[I_018:%.*]] = phi i32 [ [[ADD5:%.*]], [[FOR_BODY]] ], [ 0, [[ENTRY]] ]475; CHECK-AARCH64-NEXT:    [[Y_017:%.*]] = phi double [ [[ADD4]], [[FOR_BODY]] ], [ 0.000000e+00, [[ENTRY]] ]476; CHECK-AARCH64-NEXT:    [[X_016:%.*]] = phi double [ [[ADD]], [[FOR_BODY]] ], [ 0.000000e+00, [[ENTRY]] ]477; CHECK-AARCH64-NEXT:    [[IDXPROM:%.*]] = zext i32 [[I_018]] to i64478; CHECK-AARCH64-NEXT:    [[ARRAYIDX:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[IDXPROM]]479; CHECK-AARCH64-NEXT:    [[TMP0:%.*]] = load double, ptr [[ARRAYIDX]], align 8480; CHECK-AARCH64-NEXT:    [[ADD]] = fadd double [[X_016]], [[TMP0]]481; CHECK-AARCH64-NEXT:    [[ADD1:%.*]] = or disjoint i32 [[I_018]], 1482; CHECK-AARCH64-NEXT:    [[IDXPROM2:%.*]] = zext i32 [[ADD1]] to i64483; CHECK-AARCH64-NEXT:    [[ARRAYIDX3:%.*]] = getelementptr inbounds double, ptr [[A]], i64 [[IDXPROM2]]484; CHECK-AARCH64-NEXT:    [[TMP1:%.*]] = load double, ptr [[ARRAYIDX3]], align 8485; CHECK-AARCH64-NEXT:    [[ADD4]] = fadd double [[Y_017]], [[TMP1]]486; CHECK-AARCH64-NEXT:    [[ADD5]] = add i32 [[I_018]], 2487; CHECK-AARCH64-NEXT:    [[CMP:%.*]] = icmp ult i32 [[ADD5]], [[N]]488; CHECK-AARCH64-NEXT:    br i1 [[CMP]], label [[FOR_BODY]], label [[FOR_COND_CLEANUP]]489;490 491entry:492  %cmp15 = icmp eq i32 %n, 0493  br i1 %cmp15, label %for.cond.cleanup, label %for.body494 495for.cond.cleanup:                                 ; preds = %for.body, %entry496  %x.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add, %for.body ]497  %y.0.lcssa = phi double [ 0.000000e+00, %entry ], [ %add4, %for.body ]498  %mul = fmul double %x.0.lcssa, %y.0.lcssa499  ret double %mul500 501for.body:                                         ; preds = %entry, %for.body502  %i.018 = phi i32 [ %add5, %for.body ], [ 0, %entry ]503  %y.017 = phi double [ %add4, %for.body ], [ 0.000000e+00, %entry ]504  %x.016 = phi double [ %add, %for.body ], [ 0.000000e+00, %entry ]505  %idxprom = zext i32 %i.018 to i64506  %arrayidx = getelementptr inbounds double, ptr %a, i64 %idxprom507  %0 = load double, ptr %arrayidx, align 8508  %add = fadd double %x.016, %0509  %add1 = or disjoint i32 %i.018, 1510  %idxprom2 = zext i32 %add1 to i64511  %arrayidx3 = getelementptr inbounds double, ptr %a, i64 %idxprom2512  %1 = load double, ptr %arrayidx3, align 8513  %add4 = fadd double %y.017, %1514  %add5 = add i32 %i.018, 2515  %cmp = icmp ult i32 %add5, %n516  br i1 %cmp, label %for.body, label %for.cond.cleanup517}518 519; Globals/constant expressions are not normal constants.520; They should not be treated as the usual vectorization candidates.521 522@g1 = external global i32, align 4523@g2 = external global i32, align 4524 525define void @PR33958(ptr nocapture %p) {526; CHECK-LABEL: @PR33958(527; CHECK-NEXT:    store ptr @g1, ptr [[P:%.*]], align 8528; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds ptr, ptr [[P]], i64 1529; CHECK-NEXT:    store ptr @g2, ptr [[ARRAYIDX1]], align 8530; CHECK-NEXT:    ret void531;532  store ptr @g1, ptr %p, align 8533  %arrayidx1 = getelementptr inbounds ptr, ptr %p, i64 1534  store ptr @g2, ptr %arrayidx1, align 8535  ret void536}537 538define void @store_constant_expression(ptr %p) {539; CHECK-LABEL: @store_constant_expression(540; CHECK-NEXT:    store i64 ptrtoint (ptr @g1 to i64), ptr [[P:%.*]], align 8541; CHECK-NEXT:    [[ARRAYIDX1:%.*]] = getelementptr inbounds i64, ptr [[P]], i64 1542; CHECK-NEXT:    store i64 ptrtoint (ptr @g2 to i64), ptr [[ARRAYIDX1]], align 8543; CHECK-NEXT:    ret void544;545  store i64 ptrtoint (ptr @g1 to i64), ptr %p, align 8546  %arrayidx1 = getelementptr inbounds i64, ptr %p, i64 1547  store i64 ptrtoint (ptr @g2 to i64), ptr %arrayidx1, align 8548  ret void549}550 551!llvm.ident = !{!0}552 553!0 = !{!"clang version 3.5.0 "}554