1c7d39fd6SDavid Green; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2be51fa45SRoman Lebedev; RUN: opt %s -passes=loop-vectorize -force-vector-interleave=1 -force-vector-width=4 -S | FileCheck %s 3c7d39fd6SDavid Green 4c7d39fd6SDavid Greendefine void @signed(ptr %x, ptr %y, i32 %n) { 5c7d39fd6SDavid Green; CHECK-LABEL: @signed( 6c7d39fd6SDavid Green; CHECK-NEXT: entry: 7b7315ffcSFlorian Hahn; CHECK-NEXT: [[X2:%.*]] = ptrtoint ptr [[X:%.*]] to i64 8b7315ffcSFlorian Hahn; CHECK-NEXT: [[Y1:%.*]] = ptrtoint ptr [[Y:%.*]] to i64 9c7d39fd6SDavid Green; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[N:%.*]], 0 10c7d39fd6SDavid Green; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 11c7d39fd6SDavid Green; CHECK: for.body.preheader: 12c7d39fd6SDavid Green; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N]] to i64 136f81903eSDavid Green; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[WIDE_TRIP_COUNT]], 4 146f81903eSDavid Green; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 156f81903eSDavid Green; CHECK: vector.memcheck: 16b7315ffcSFlorian Hahn; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[Y1]], [[X2]] 17b7315ffcSFlorian Hahn; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 16 18b7315ffcSFlorian Hahn; CHECK-NEXT: br i1 [[DIFF_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 196f81903eSDavid Green; CHECK: vector.ph: 206f81903eSDavid Green; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[WIDE_TRIP_COUNT]], 4 216f81903eSDavid Green; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[WIDE_TRIP_COUNT]], [[N_MOD_VF]] 226f81903eSDavid Green; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 236f81903eSDavid Green; CHECK: vector.body: 246f81903eSDavid Green; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 256f81903eSDavid Green; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 0 266f81903eSDavid Green; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds float, ptr [[X]], i64 [[TMP1]] 276f81903eSDavid Green; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i32 0 28b7315ffcSFlorian Hahn; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP3]], align 4 296f81903eSDavid Green; CHECK-NEXT: [[TMP4:%.*]] = call <4 x i32> @llvm.fptosi.sat.v4i32.v4f32(<4 x float> [[WIDE_LOAD]]) 306f81903eSDavid Green; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[Y]], i64 [[TMP1]] 316f81903eSDavid Green; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 0 32b7315ffcSFlorian Hahn; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr [[TMP6]], align 4 336f81903eSDavid Green; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 346f81903eSDavid Green; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 35b7315ffcSFlorian Hahn; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP0:![0-9]+]] 366f81903eSDavid Green; CHECK: middle.block: 376f81903eSDavid Green; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[WIDE_TRIP_COUNT]], [[N_VEC]] 386f81903eSDavid Green; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[SCALAR_PH]] 396f81903eSDavid Green; CHECK: scalar.ph: 40*4ad0fdd1SFlorian Hahn; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 41c7d39fd6SDavid Green; CHECK-NEXT: br label [[FOR_BODY:%.*]] 42c7d39fd6SDavid Green; CHECK: for.cond.cleanup.loopexit: 43c7d39fd6SDavid Green; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 44c7d39fd6SDavid Green; CHECK: for.cond.cleanup: 45c7d39fd6SDavid Green; CHECK-NEXT: ret void 46c7d39fd6SDavid Green; CHECK: for.body: 476f81903eSDavid Green; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 486f81903eSDavid Green; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[X]], i64 [[INDVARS_IV]] 496f81903eSDavid Green; CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX]], align 4 506f81903eSDavid Green; CHECK-NEXT: [[TMP9:%.*]] = tail call i32 @llvm.fptosi.sat.i32.f32(float [[TMP8]]) 516f81903eSDavid Green; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[Y]], i64 [[INDVARS_IV]] 526f81903eSDavid Green; CHECK-NEXT: store i32 [[TMP9]], ptr [[ARRAYIDX2]], align 4 53c7d39fd6SDavid Green; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 54c7d39fd6SDavid Green; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 55*4ad0fdd1SFlorian Hahn; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY]], !llvm.loop [[LOOP3:![0-9]+]] 56c7d39fd6SDavid Green; 57c7d39fd6SDavid Greenentry: 58c7d39fd6SDavid Green %cmp6 = icmp sgt i32 %n, 0 59c7d39fd6SDavid Green br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup 60c7d39fd6SDavid Green 61c7d39fd6SDavid Greenfor.body.preheader: ; preds = %entry 62c7d39fd6SDavid Green %wide.trip.count = zext i32 %n to i64 63c7d39fd6SDavid Green br label %for.body 64c7d39fd6SDavid Green 65c7d39fd6SDavid Greenfor.cond.cleanup: ; preds = %for.body, %entry 66c7d39fd6SDavid Green ret void 67c7d39fd6SDavid Green 68c7d39fd6SDavid Greenfor.body: ; preds = %for.body.preheader, %for.body 69c7d39fd6SDavid Green %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 70c7d39fd6SDavid Green %arrayidx = getelementptr inbounds float, ptr %x, i64 %indvars.iv 71c7d39fd6SDavid Green %0 = load float, ptr %arrayidx, align 4 72c7d39fd6SDavid Green %1 = tail call i32 @llvm.fptosi.sat.i32.f32(float %0) 73c7d39fd6SDavid Green %arrayidx2 = getelementptr inbounds i32, ptr %y, i64 %indvars.iv 74c7d39fd6SDavid Green store i32 %1, ptr %arrayidx2, align 4 75c7d39fd6SDavid Green %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 76c7d39fd6SDavid Green %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count 77c7d39fd6SDavid Green br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 78c7d39fd6SDavid Green} 79c7d39fd6SDavid Green 80c7d39fd6SDavid Greendefine void @unsigned(ptr %x, ptr %y, i32 %n) { 81c7d39fd6SDavid Green; CHECK-LABEL: @unsigned( 82c7d39fd6SDavid Green; CHECK-NEXT: entry: 83b7315ffcSFlorian Hahn; CHECK-NEXT: [[X2:%.*]] = ptrtoint ptr [[X:%.*]] to i64 84b7315ffcSFlorian Hahn; CHECK-NEXT: [[Y1:%.*]] = ptrtoint ptr [[Y:%.*]] to i64 85c7d39fd6SDavid Green; CHECK-NEXT: [[CMP6:%.*]] = icmp sgt i32 [[N:%.*]], 0 86c7d39fd6SDavid Green; CHECK-NEXT: br i1 [[CMP6]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_COND_CLEANUP:%.*]] 87c7d39fd6SDavid Green; CHECK: for.body.preheader: 88c7d39fd6SDavid Green; CHECK-NEXT: [[WIDE_TRIP_COUNT:%.*]] = zext i32 [[N]] to i64 896f81903eSDavid Green; CHECK-NEXT: [[MIN_ITERS_CHECK:%.*]] = icmp ult i64 [[WIDE_TRIP_COUNT]], 4 906f81903eSDavid Green; CHECK-NEXT: br i1 [[MIN_ITERS_CHECK]], label [[SCALAR_PH:%.*]], label [[VECTOR_MEMCHECK:%.*]] 916f81903eSDavid Green; CHECK: vector.memcheck: 92b7315ffcSFlorian Hahn; CHECK-NEXT: [[TMP0:%.*]] = sub i64 [[Y1]], [[X2]] 93b7315ffcSFlorian Hahn; CHECK-NEXT: [[DIFF_CHECK:%.*]] = icmp ult i64 [[TMP0]], 16 94b7315ffcSFlorian Hahn; CHECK-NEXT: br i1 [[DIFF_CHECK]], label [[SCALAR_PH]], label [[VECTOR_PH:%.*]] 956f81903eSDavid Green; CHECK: vector.ph: 966f81903eSDavid Green; CHECK-NEXT: [[N_MOD_VF:%.*]] = urem i64 [[WIDE_TRIP_COUNT]], 4 976f81903eSDavid Green; CHECK-NEXT: [[N_VEC:%.*]] = sub i64 [[WIDE_TRIP_COUNT]], [[N_MOD_VF]] 986f81903eSDavid Green; CHECK-NEXT: br label [[VECTOR_BODY:%.*]] 996f81903eSDavid Green; CHECK: vector.body: 1006f81903eSDavid Green; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[VECTOR_PH]] ], [ [[INDEX_NEXT:%.*]], [[VECTOR_BODY]] ] 1016f81903eSDavid Green; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[INDEX]], 0 1026f81903eSDavid Green; CHECK-NEXT: [[TMP2:%.*]] = getelementptr inbounds float, ptr [[X]], i64 [[TMP1]] 1036f81903eSDavid Green; CHECK-NEXT: [[TMP3:%.*]] = getelementptr inbounds float, ptr [[TMP2]], i32 0 104b7315ffcSFlorian Hahn; CHECK-NEXT: [[WIDE_LOAD:%.*]] = load <4 x float>, ptr [[TMP3]], align 4 1056f81903eSDavid Green; CHECK-NEXT: [[TMP4:%.*]] = call <4 x i32> @llvm.fptoui.sat.v4i32.v4f32(<4 x float> [[WIDE_LOAD]]) 1066f81903eSDavid Green; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds i32, ptr [[Y]], i64 [[TMP1]] 1076f81903eSDavid Green; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds i32, ptr [[TMP5]], i32 0 108b7315ffcSFlorian Hahn; CHECK-NEXT: store <4 x i32> [[TMP4]], ptr [[TMP6]], align 4 1096f81903eSDavid Green; CHECK-NEXT: [[INDEX_NEXT]] = add nuw i64 [[INDEX]], 4 1106f81903eSDavid Green; CHECK-NEXT: [[TMP7:%.*]] = icmp eq i64 [[INDEX_NEXT]], [[N_VEC]] 111*4ad0fdd1SFlorian Hahn; CHECK-NEXT: br i1 [[TMP7]], label [[MIDDLE_BLOCK:%.*]], label [[VECTOR_BODY]], !llvm.loop [[LOOP4:![0-9]+]] 1126f81903eSDavid Green; CHECK: middle.block: 1136f81903eSDavid Green; CHECK-NEXT: [[CMP_N:%.*]] = icmp eq i64 [[WIDE_TRIP_COUNT]], [[N_VEC]] 1146f81903eSDavid Green; CHECK-NEXT: br i1 [[CMP_N]], label [[FOR_COND_CLEANUP_LOOPEXIT:%.*]], label [[SCALAR_PH]] 1156f81903eSDavid Green; CHECK: scalar.ph: 116*4ad0fdd1SFlorian Hahn; CHECK-NEXT: [[BC_RESUME_VAL:%.*]] = phi i64 [ [[N_VEC]], [[MIDDLE_BLOCK]] ], [ 0, [[VECTOR_MEMCHECK]] ], [ 0, [[FOR_BODY_PREHEADER]] ] 117c7d39fd6SDavid Green; CHECK-NEXT: br label [[FOR_BODY:%.*]] 118c7d39fd6SDavid Green; CHECK: for.cond.cleanup.loopexit: 119c7d39fd6SDavid Green; CHECK-NEXT: br label [[FOR_COND_CLEANUP]] 120c7d39fd6SDavid Green; CHECK: for.cond.cleanup: 121c7d39fd6SDavid Green; CHECK-NEXT: ret void 122c7d39fd6SDavid Green; CHECK: for.body: 1236f81903eSDavid Green; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[BC_RESUME_VAL]], [[SCALAR_PH]] ], [ [[INDVARS_IV_NEXT:%.*]], [[FOR_BODY]] ] 1246f81903eSDavid Green; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds float, ptr [[X]], i64 [[INDVARS_IV]] 1256f81903eSDavid Green; CHECK-NEXT: [[TMP8:%.*]] = load float, ptr [[ARRAYIDX]], align 4 1266f81903eSDavid Green; CHECK-NEXT: [[TMP9:%.*]] = tail call i32 @llvm.fptoui.sat.i32.f32(float [[TMP8]]) 1276f81903eSDavid Green; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[Y]], i64 [[INDVARS_IV]] 1286f81903eSDavid Green; CHECK-NEXT: store i32 [[TMP9]], ptr [[ARRAYIDX2]], align 4 129c7d39fd6SDavid Green; CHECK-NEXT: [[INDVARS_IV_NEXT]] = add nuw nsw i64 [[INDVARS_IV]], 1 130c7d39fd6SDavid Green; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i64 [[INDVARS_IV_NEXT]], [[WIDE_TRIP_COUNT]] 131*4ad0fdd1SFlorian Hahn; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label [[FOR_COND_CLEANUP_LOOPEXIT]], label [[FOR_BODY]], !llvm.loop [[LOOP5:![0-9]+]] 132c7d39fd6SDavid Green; 133c7d39fd6SDavid Greenentry: 134c7d39fd6SDavid Green %cmp6 = icmp sgt i32 %n, 0 135c7d39fd6SDavid Green br i1 %cmp6, label %for.body.preheader, label %for.cond.cleanup 136c7d39fd6SDavid Green 137c7d39fd6SDavid Greenfor.body.preheader: ; preds = %entry 138c7d39fd6SDavid Green %wide.trip.count = zext i32 %n to i64 139c7d39fd6SDavid Green br label %for.body 140c7d39fd6SDavid Green 141c7d39fd6SDavid Greenfor.cond.cleanup: ; preds = %for.body, %entry 142c7d39fd6SDavid Green ret void 143c7d39fd6SDavid Green 144c7d39fd6SDavid Greenfor.body: ; preds = %for.body.preheader, %for.body 145c7d39fd6SDavid Green %indvars.iv = phi i64 [ 0, %for.body.preheader ], [ %indvars.iv.next, %for.body ] 146c7d39fd6SDavid Green %arrayidx = getelementptr inbounds float, ptr %x, i64 %indvars.iv 147c7d39fd6SDavid Green %0 = load float, ptr %arrayidx, align 4 148c7d39fd6SDavid Green %1 = tail call i32 @llvm.fptoui.sat.i32.f32(float %0) 149c7d39fd6SDavid Green %arrayidx2 = getelementptr inbounds i32, ptr %y, i64 %indvars.iv 150c7d39fd6SDavid Green store i32 %1, ptr %arrayidx2, align 4 151c7d39fd6SDavid Green %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1 152c7d39fd6SDavid Green %exitcond.not = icmp eq i64 %indvars.iv.next, %wide.trip.count 153c7d39fd6SDavid Green br i1 %exitcond.not, label %for.cond.cleanup, label %for.body 154c7d39fd6SDavid Green} 155c7d39fd6SDavid Green 156c7d39fd6SDavid Greendeclare i32 @llvm.fptosi.sat.i32.f32(float) 157c7d39fd6SDavid Greendeclare i32 @llvm.fptoui.sat.i32.f32(float) 158