1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -basic-aa -loop-vectorize < %s | FileCheck %s 3target datalayout = "E-m:e-i64:64-n32:64" 4target triple = "powerpc64-unknown-linux-gnu" 5 6; Function Attrs: nounwind 7define void @foo(double* noalias nocapture %a, double* noalias nocapture readonly %b) #0 { 8; CHECK-LABEL: @foo( 9; CHECK-NEXT: entry: 10; CHECK-NEXT: br i1 false, label [[SCALAR_PH:%.*]], label [[VECTOR_PH:%.*]] 11; CHECK: vector.ph: 12; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 13; CHECK: vector.body: 14; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 15; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[INDEX]], 0 16; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 2 17; CHECK-NEXT: [[TMP2:%.*]] = add i64 [[INDEX]], 4 18; CHECK-NEXT: [[TMP3:%.*]] = add i64 [[INDEX]], 6 19; CHECK-NEXT: [[TMP4:%.*]] = add i64 [[INDEX]], 8 20; CHECK-NEXT: [[TMP5:%.*]] = add i64 [[INDEX]], 10 21; CHECK-NEXT: [[TMP6:%.*]] = add i64 [[INDEX]], 12 22; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[INDEX]], 14 23; CHECK-NEXT: [[TMP8:%.*]] = shl nsw i64 [[TMP0]], 1 24; CHECK-NEXT: [[TMP9:%.*]] = shl nsw i64 [[TMP1]], 1 25; CHECK-NEXT: [[TMP10:%.*]] = shl nsw i64 [[TMP2]], 1 26; CHECK-NEXT: [[TMP11:%.*]] = shl nsw i64 [[TMP3]], 1 27; CHECK-NEXT: [[TMP12:%.*]] = shl nsw i64 [[TMP4]], 1 28; CHECK-NEXT: [[TMP13:%.*]] = shl nsw i64 [[TMP5]], 1 29; CHECK-NEXT: [[TMP14:%.*]] = shl nsw i64 [[TMP6]], 1 30; CHECK-NEXT: [[TMP15:%.*]] = shl nsw i64 [[TMP7]], 1 31; CHECK-NEXT: [[TMP16:%.*]] = getelementptr inbounds double, double* [[B:%.*]], i64 [[TMP8]] 32; CHECK-NEXT: [[TMP17:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP9]] 33; CHECK-NEXT: [[TMP18:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP10]] 34; CHECK-NEXT: [[TMP19:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP11]] 35; CHECK-NEXT: [[TMP20:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP12]] 36; CHECK-NEXT: [[TMP21:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP13]] 37; CHECK-NEXT: [[TMP22:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP14]] 38; CHECK-NEXT: [[TMP23:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP15]] 39; CHECK-NEXT: [[TMP24:%.*]] = getelementptr inbounds double, double* [[TMP16]], i32 0 40; CHECK-NEXT: [[TMP25:%.*]] = bitcast double* [[TMP24]] to <4 x double>* 41; CHECK-NEXT: [[TMP26:%.*]] = getelementptr inbounds double, double* [[TMP17]], i32 0 42; CHECK-NEXT: [[TMP27:%.*]] = bitcast double* [[TMP26]] to <4 x double>* 43; CHECK-NEXT: [[TMP28:%.*]] = getelementptr inbounds double, double* [[TMP18]], i32 0 44; CHECK-NEXT: [[TMP29:%.*]] = bitcast double* [[TMP28]] to <4 x double>* 45; CHECK-NEXT: [[TMP30:%.*]] = getelementptr inbounds double, double* [[TMP19]], i32 0 46; CHECK-NEXT: [[TMP31:%.*]] = bitcast double* [[TMP30]] to <4 x double>* 47; CHECK-NEXT: [[TMP32:%.*]] = getelementptr inbounds double, double* [[TMP20]], i32 0 48; CHECK-NEXT: [[TMP33:%.*]] = bitcast double* [[TMP32]] to <4 x double>* 49; CHECK-NEXT: [[TMP34:%.*]] = getelementptr inbounds double, double* [[TMP21]], i32 0 50; CHECK-NEXT: [[TMP35:%.*]] = bitcast double* [[TMP34]] to <4 x double>* 51; CHECK-NEXT: [[TMP36:%.*]] = getelementptr inbounds double, double* [[TMP22]], i32 0 52; CHECK-NEXT: [[TMP37:%.*]] = bitcast double* [[TMP36]] to <4 x double>* 53; CHECK-NEXT: [[TMP38:%.*]] = getelementptr inbounds double, double* [[TMP23]], i32 0 54; CHECK-NEXT: [[TMP39:%.*]] = bitcast double* [[TMP38]] to <4 x double>* 55; CHECK-NEXT: [[WIDE_VEC:%.*]] = load <4 x double>, <4 x double>* [[TMP25]], align 8 56; CHECK-NEXT: [[WIDE_VEC1:%.*]] = load <4 x double>, <4 x double>* [[TMP27]], align 8 57; CHECK-NEXT: [[WIDE_VEC2:%.*]] = load <4 x double>, <4 x double>* [[TMP29]], align 8 58; CHECK-NEXT: [[WIDE_VEC3:%.*]] = load <4 x double>, <4 x double>* [[TMP31]], align 8 59; CHECK-NEXT: [[WIDE_VEC4:%.*]] = load <4 x double>, <4 x double>* [[TMP33]], align 8 60; CHECK-NEXT: [[WIDE_VEC5:%.*]] = load <4 x double>, <4 x double>* [[TMP35]], align 8 61; CHECK-NEXT: [[WIDE_VEC6:%.*]] = load <4 x double>, <4 x double>* [[TMP37]], align 8 62; CHECK-NEXT: [[WIDE_VEC7:%.*]] = load <4 x double>, <4 x double>* [[TMP39]], align 8 63; CHECK-NEXT: [[STRIDED_VEC:%.*]] = shufflevector <4 x double> [[WIDE_VEC]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 64; CHECK-NEXT: [[STRIDED_VEC8:%.*]] = shufflevector <4 x double> [[WIDE_VEC1]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 65; CHECK-NEXT: [[STRIDED_VEC9:%.*]] = shufflevector <4 x double> [[WIDE_VEC2]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 66; CHECK-NEXT: [[STRIDED_VEC10:%.*]] = shufflevector <4 x double> [[WIDE_VEC3]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 67; CHECK-NEXT: [[STRIDED_VEC11:%.*]] = shufflevector <4 x double> [[WIDE_VEC4]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 68; CHECK-NEXT: [[STRIDED_VEC12:%.*]] = shufflevector <4 x double> [[WIDE_VEC5]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 69; CHECK-NEXT: [[STRIDED_VEC13:%.*]] = shufflevector <4 x double> [[WIDE_VEC6]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 70; CHECK-NEXT: [[STRIDED_VEC14:%.*]] = shufflevector <4 x double> [[WIDE_VEC7]], <4 x double> poison, <2 x i32> <i32 0, i32 2> 71; CHECK-NEXT: [[STRIDED_VEC15:%.*]] = shufflevector <4 x double> [[WIDE_VEC]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 72; CHECK-NEXT: [[STRIDED_VEC16:%.*]] = shufflevector <4 x double> [[WIDE_VEC1]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 73; CHECK-NEXT: [[STRIDED_VEC17:%.*]] = shufflevector <4 x double> [[WIDE_VEC2]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 74; CHECK-NEXT: [[STRIDED_VEC18:%.*]] = shufflevector <4 x double> [[WIDE_VEC3]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 75; CHECK-NEXT: [[STRIDED_VEC19:%.*]] = shufflevector <4 x double> [[WIDE_VEC4]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 76; CHECK-NEXT: [[STRIDED_VEC20:%.*]] = shufflevector <4 x double> [[WIDE_VEC5]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 77; CHECK-NEXT: [[STRIDED_VEC21:%.*]] = shufflevector <4 x double> [[WIDE_VEC6]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 78; CHECK-NEXT: [[STRIDED_VEC22:%.*]] = shufflevector <4 x double> [[WIDE_VEC7]], <4 x double> poison, <2 x i32> <i32 1, i32 3> 79; CHECK-NEXT: [[TMP40:%.*]] = fadd <2 x double> [[STRIDED_VEC]], [[STRIDED_VEC15]] 80; CHECK-NEXT: [[TMP41:%.*]] = fadd <2 x double> [[STRIDED_VEC8]], [[STRIDED_VEC16]] 81; CHECK-NEXT: [[TMP42:%.*]] = fadd <2 x double> [[STRIDED_VEC9]], [[STRIDED_VEC17]] 82; CHECK-NEXT: [[TMP43:%.*]] = fadd <2 x double> [[STRIDED_VEC10]], [[STRIDED_VEC18]] 83; CHECK-NEXT: [[TMP44:%.*]] = fadd <2 x double> [[STRIDED_VEC11]], [[STRIDED_VEC19]] 84; CHECK-NEXT: [[TMP45:%.*]] = fadd <2 x double> [[STRIDED_VEC12]], [[STRIDED_VEC20]] 85; CHECK-NEXT: [[TMP46:%.*]] = fadd <2 x double> [[STRIDED_VEC13]], [[STRIDED_VEC21]] 86; CHECK-NEXT: [[TMP47:%.*]] = fadd <2 x double> [[STRIDED_VEC14]], [[STRIDED_VEC22]] 87; CHECK-NEXT: [[TMP48:%.*]] = getelementptr inbounds double, double* [[A:%.*]], i64 [[TMP0]] 88; CHECK-NEXT: [[TMP49:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP1]] 89; CHECK-NEXT: [[TMP50:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP2]] 90; CHECK-NEXT: [[TMP51:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP3]] 91; CHECK-NEXT: [[TMP52:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP4]] 92; CHECK-NEXT: [[TMP53:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP5]] 93; CHECK-NEXT: [[TMP54:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP6]] 94; CHECK-NEXT: [[TMP55:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[TMP7]] 95; CHECK-NEXT: [[TMP56:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 0 96; CHECK-NEXT: [[TMP57:%.*]] = bitcast double* [[TMP56]] to <2 x double>* 97; CHECK-NEXT: store <2 x double> [[TMP40]], <2 x double>* [[TMP57]], align 8 98; CHECK-NEXT: [[TMP58:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 2 99; CHECK-NEXT: [[TMP59:%.*]] = bitcast double* [[TMP58]] to <2 x double>* 100; CHECK-NEXT: store <2 x double> [[TMP41]], <2 x double>* [[TMP59]], align 8 101; CHECK-NEXT: [[TMP60:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 4 102; CHECK-NEXT: [[TMP61:%.*]] = bitcast double* [[TMP60]] to <2 x double>* 103; CHECK-NEXT: store <2 x double> [[TMP42]], <2 x double>* [[TMP61]], align 8 104; CHECK-NEXT: [[TMP62:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 6 105; CHECK-NEXT: [[TMP63:%.*]] = bitcast double* [[TMP62]] to <2 x double>* 106; CHECK-NEXT: store <2 x double> [[TMP43]], <2 x double>* [[TMP63]], align 8 107; CHECK-NEXT: [[TMP64:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 8 108; CHECK-NEXT: [[TMP65:%.*]] = bitcast double* [[TMP64]] to <2 x double>* 109; CHECK-NEXT: store <2 x double> [[TMP44]], <2 x double>* [[TMP65]], align 8 110; CHECK-NEXT: [[TMP66:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 10 111; CHECK-NEXT: [[TMP67:%.*]] = bitcast double* [[TMP66]] to <2 x double>* 112; CHECK-NEXT: store <2 x double> [[TMP45]], <2 x double>* [[TMP67]], align 8 113; CHECK-NEXT: [[TMP68:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 12 114; CHECK-NEXT: [[TMP69:%.*]] = bitcast double* [[TMP68]] to <2 x double>* 115; CHECK-NEXT: store <2 x double> [[TMP46]], <2 x double>* [[TMP69]], align 8 116; CHECK-NEXT: [[TMP70:%.*]] = getelementptr inbounds double, double* [[TMP48]], i32 14 117; CHECK-NEXT: [[TMP71:%.*]] = bitcast double* [[TMP70]] to <2 x double>* 118; CHECK-NEXT: store <2 x double> [[TMP47]], <2 x double>* [[TMP71]], align 8 119; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 16 120; CHECK-NEXT: [[TMP72:%.*]] = icmp eq i64 [[INDEX_NEXT]], 1600 121; CHECK-NEXT: br i1 [[TMP72]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 122; CHECK: middle.block: 123; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 1600, 1600 124; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP:%.*]], label [[SCALAR_PH]] 125; CHECK: scalar.ph: 126; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ 1600, [[MIDDLE_BLOCK]] ], [ 0, [[ENTRY:%.*]] ] 127; CHECK-NEXT: br label [[FOR_BODY:%.*]] 128; CHECK: for.cond.cleanup: 129; CHECK-NEXT: ret void 130; CHECK: for.body: 131; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 132; CHECK-NEXT: [[TMP73:%.*]] = shl nsw i64 [[INDVARS_IV]], 1 133; CHECK-NEXT: [[ODD_IDX:%.*]] = add nsw i64 [[TMP73]], 1 134; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[TMP73]] 135; CHECK-NEXT: [[ARRAYIDX_ODD:%.*]] = getelementptr inbounds double, double* [[B]], i64 [[ODD_IDX]] 136; CHECK-NEXT: [[TMP74:%.*]] = load double, double* [[ARRAYIDX]], align 8 137; CHECK-NEXT: [[TMP75:%.*]] = load double, double* [[ARRAYIDX_ODD]], align 8 138; CHECK-NEXT: [[ADD:%.*]] = fadd double [[TMP74]], [[TMP75]] 139; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds double, double* [[A]], i64 [[INDVARS_IV]] 140; CHECK-NEXT: store double [[ADD]], double* [[ARRAYIDX2]], align 8 141; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 142; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], 1600 143; CHECK-NEXT: br i1 [[EXITCOND]], label [[FOR_COND_CLEANUP]], label [[FOR_BODY]], !llvm.loop [[LOOP2:![0-9]+]] 144; 145entry: 146 br label %for.body 147 148 149for.cond.cleanup: ; preds = %for.body 150 ret void 151 152for.body: ; preds = %for.body, %entry 153 %indvars.iv = phi i64 [ 0, %entry ], [ %indvars.iv.next, %for.body ] 154 %0 = shl nsw i64 %indvars.iv, 1 155 %odd.idx = add nsw i64 %0, 1 156 157 %arrayidx = getelementptr inbounds double, double* %b, i64 %0 158 %arrayidx.odd = getelementptr inbounds double, double* %b, i64 %odd.idx 159 160 %1 = load double, double* %arrayidx, align 8 161 %2 = load double, double* %arrayidx.odd, align 8 162 163 %add = fadd double %1, %2 164 %arrayidx2 = getelementptr inbounds double, double* %a, i64 %indvars.iv 165 store double %add, double* %arrayidx2, align 8 166 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 167 %exitcond = icmp eq i64 %indvars.iv.next, 1600 168 br i1 %exitcond, label %for.cond.cleanup, label %for.body 169} 170 171attributes #0 = { nounwind "target-cpu"="pwr8" } 172 173