llvm.org GIT mirror llvm / fcdf36f
[LV] Transform truncations of non-primary induction variables The vectorizer tries to replace truncations of induction variables with new induction variables having the smaller type. After r295063, this optimization was applied to all integer induction variables, including non-primary ones. When optimizing the truncation of a non-primary induction variable, we still need to transform the new induction so that it has the correct start value. This should fix PR32419. Reference: https://bugs.llvm.org/show_bug.cgi?id=32419 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@298882 91177308-0d34-0410-b5e6-96231b3b80d8 Matthew Simpson 3 years ago
2 changed file(s) with 55 addition(s) and 11 deletion(s). Raw diff Collapse all Expand all
25202520 // induction variable and step. Otherwise, derive these values from the
25212521 // induction descriptor.
25222522 if (!VectorizedIV || NeedsScalarIV) {
2523 ScalarIV = Induction;
2524 if (IV != OldInduction) {
2525 ScalarIV = IV->getType()->isIntegerTy()
2526 ? Builder.CreateSExtOrTrunc(Induction, IV->getType())
2527 : Builder.CreateCast(Instruction::SIToFP, Induction,
2528 IV->getType());
2529 ScalarIV = ID.transform(Builder, ScalarIV, PSE.getSE(), DL);
2530 ScalarIV->setName("offset.idx");
2531 }
25232532 if (Trunc) {
25242533 auto *TruncType = cast(Trunc->getType());
25252534 assert(Step->getType()->isIntegerTy() &&
25262535 "Truncation requires an integer step");
2527 ScalarIV = Builder.CreateCast(Instruction::Trunc, Induction, TruncType);
2536 ScalarIV = Builder.CreateTrunc(ScalarIV, TruncType);
25282537 Step = Builder.CreateTrunc(Step, TruncType);
2529 } else {
2530 ScalarIV = Induction;
2531 if (IV != OldInduction) {
2532 ScalarIV = IV->getType()->isIntegerTy()
2533 ? Builder.CreateSExtOrTrunc(ScalarIV, IV->getType())
2534 : Builder.CreateCast(Instruction::SIToFP, Induction,
2535 IV->getType());
2536 ScalarIV = ID.transform(Builder, ScalarIV, PSE.getSE(), DL);
2537 ScalarIV->setName("offset.idx");
2538 }
25392538 }
25402539 }
25412540
803803 for.end:
804804 ret void
805805 }
806
807 ; PR32419. Ensure we transform truncated non-primary induction variables. In
808 ; the test case below we replace %tmp1 with a new induction variable. Because
809 ; the truncated value is non-primary, we must compute an offset from the
810 ; primary induction variable.
811 ;
812 ; CHECK-LABEL: @PR32419(
813 ; CHECK: vector.body:
814 ; CHECK-NEXT: [[INDEX:%.*]] = phi i32 [ 0, %vector.ph ], [ [[INDEX_NEXT:%.*]], %[[PRED_UREM_CONTINUE4:.*]] ]
815 ; CHECK: [[OFFSET_IDX:%.*]] = add i32 -20, [[INDEX]]
816 ; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[OFFSET_IDX]] to i16
817 ; CHECK: [[TMP8:%.*]] = add i16 [[TMP1]], 0
818 ; CHECK-NEXT: [[TMP9:%.*]] = urem i16 %b, [[TMP8]]
819 ; CHECK: [[TMP15:%.*]] = add i16 [[TMP1]], 1
820 ; CHECK-NEXT: [[TMP16:%.*]] = urem i16 %b, [[TMP15]]
821 ; CHECK: [[PRED_UREM_CONTINUE4]]:
822 ; CHECK: br i1 {{.*}}, label %middle.block, label %vector.body
823 ;
824 define i32 @PR32419(i32 %a, i16 %b) {
825 entry:
826 br label %for.body
827
828 for.body:
829 %i = phi i32 [ -20, %entry ], [ %i.next, %for.inc ]
830 %tmp0 = phi i32 [ %a, %entry ], [ %tmp6, %for.inc ]
831 %tmp1 = trunc i32 %i to i16
832 %tmp2 = icmp eq i16 %tmp1, 0
833 br i1 %tmp2, label %for.inc, label %for.cond
834
835 for.cond:
836 %tmp3 = urem i16 %b, %tmp1
837 br label %for.inc
838
839 for.inc:
840 %tmp4 = phi i16 [ %tmp3, %for.cond ], [ 0, %for.body ]
841 %tmp5 = sext i16 %tmp4 to i32
842 %tmp6 = or i32 %tmp0, %tmp5
843 %i.next = add nsw i32 %i, 1
844 %cond = icmp eq i32 %i.next, 0
845 br i1 %cond, label %for.end, label %for.body
846
847 for.end:
848 %tmp7 = phi i32 [ %tmp6, %for.inc ]
849 ret i32 %tmp7
850 }