diff --git a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp --- a/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp +++ b/llvm/lib/Transforms/Scalar/IndVarSimplify.cpp @@ -1281,7 +1281,7 @@ MadeAnyChanges = true; ToMove->moveBefore(*ExitBlock, InsertPt); - SE->forgetBlockAndLoopDispositions(ToMove); + SE->forgetValue(ToMove); if (Done) break; InsertPt = ToMove->getIterator(); } diff --git a/llvm/test/Transforms/IndVarSimplify/pr58662.ll b/llvm/test/Transforms/IndVarSimplify/pr58662.ll new file mode 100644 --- /dev/null +++ b/llvm/test/Transforms/IndVarSimplify/pr58662.ll @@ -0,0 +1,99 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -indvars -S < %s | FileCheck %s + +; Check that the scalar evolution expression is forgot after the instruction being sunk. +@f = dso_local global i16 0, align 2 +@a = dso_local global i32 0, align 4 +@b = dso_local global i32 0, align 4 +@d = dso_local global i32 0, align 4 +@e = dso_local global i32 0, align 4 +@g = dso_local global i8 0, align 1 + +define dso_local zeroext i8 @l() local_unnamed_addr { +; CHECK-LABEL: @l( +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @b, align 4 +; CHECK-NEXT: [[A_PROMOTED:%.*]] = load i32, ptr @a, align 4 +; CHECK-NEXT: br label [[FOR_COND:%.*]] +; CHECK: for.cond: +; CHECK-NEXT: [[INC8:%.*]] = phi i32 [ [[A_PROMOTED]], [[ENTRY:%.*]] ], [ [[INC:%.*]], [[H_EXIT:%.*]] ] +; CHECK-NEXT: [[STOREMERGE:%.*]] = phi i16 [ 0, [[ENTRY]] ], [ [[SUB6:%.*]], [[H_EXIT]] ] +; CHECK-NEXT: [[INC]] = add nsw i32 [[INC8]], 1 +; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[STOREMERGE]] to i32 +; CHECK-NEXT: [[SUB:%.*]] = add nsw i32 [[CONV]], -6 +; CHECK-NEXT: br label [[WHILE_BODY_I:%.*]] +; CHECK: while.body.i: +; CHECK-NEXT: [[C_05_I:%.*]] = phi i32 [ [[INC_I:%.*]], [[WHILE_BODY_I]] ], [ 0, [[FOR_COND]] ] +; CHECK-NEXT: [[I_ADDR_04_I:%.*]] = phi i32 [ [[SHR_I:%.*]], [[WHILE_BODY_I]] ], [ [[SUB]], [[FOR_COND]] ] +; CHECK-NEXT: [[SHR_I]] = ashr i32 [[I_ADDR_04_I]], 1 +; CHECK-NEXT: [[INC_I]] = add nuw nsw i32 [[C_05_I]], 1 +; CHECK-NEXT: [[CMP_I:%.*]] = icmp ugt i32 [[C_05_I]], 5 +; CHECK-NEXT: [[TOBOOL_NOT_I:%.*]] = icmp ult i32 [[I_ADDR_04_I]], 4 +; CHECK-NEXT: [[OR_COND_I:%.*]] = select i1 [[CMP_I]], i1 true, i1 [[TOBOOL_NOT_I]] +; CHECK-NEXT: br i1 [[OR_COND_I]], label [[H_EXIT]], label [[WHILE_BODY_I]] +; CHECK: h.exit: +; CHECK-NEXT: [[INC_I_LCSSA:%.*]] = phi i32 [ [[INC_I]], [[WHILE_BODY_I]] ] +; CHECK-NEXT: [[AND:%.*]] = and i32 [[TMP0]], [[INC]] +; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[AND]] to i8 +; CHECK-NEXT: [[TMP2:%.*]] = trunc i32 [[INC_I_LCSSA]] to i8 +; CHECK-NEXT: [[TMP3:%.*]] = sub i8 [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TOBOOL_NOT:%.*]] = icmp eq i8 [[TMP3]], 17 +; CHECK-NEXT: [[SUB6]] = add i16 [[STOREMERGE]], -8 +; CHECK-NEXT: br i1 [[TOBOOL_NOT]], label [[FOR_COND]], label [[IF_THEN:%.*]] +; CHECK: if.then: +; CHECK-NEXT: [[STOREMERGE_LCSSA:%.*]] = phi i16 [ [[STOREMERGE]], [[H_EXIT]] ] +; CHECK-NEXT: [[INC_LCSSA:%.*]] = phi i32 [ [[INC]], [[H_EXIT]] ] +; CHECK-NEXT: [[AND_LCSSA:%.*]] = phi i32 [ [[AND]], [[H_EXIT]] ] +; CHECK-NEXT: [[INC_I_LCSSA_LCSSA:%.*]] = phi i32 [ [[INC_I_LCSSA]], [[H_EXIT]] ] +; CHECK-NEXT: store i16 [[STOREMERGE_LCSSA]], ptr @f, align 2 +; CHECK-NEXT: store i32 [[INC_LCSSA]], ptr @a, align 4 +; CHECK-NEXT: store i32 [[AND_LCSSA]], ptr @d, align 4 +; CHECK-NEXT: store i32 [[INC_I_LCSSA_LCSSA]], ptr @e, align 4 +; CHECK-NEXT: [[TMP4:%.*]] = load i8, ptr @g, align 1 +; CHECK-NEXT: ret i8 [[TMP4]] +; +entry: + %0 = load i32, ptr @b, align 4 + %a.promoted = load i32, ptr @a, align 4 + br label %for.cond + +for.cond: ; preds = %h.exit, %entry + %inc8 = phi i32 [ %a.promoted, %entry ], [ %inc, %h.exit ] + %storemerge = phi i16 [ 0, %entry ], [ %sub6, %h.exit ] + %inc = add nsw i32 %inc8, 1 + %and = and i32 %0, %inc + %conv = sext i16 %storemerge to i32 + %sub = add nsw i32 %conv, -6 + br label %while.body.i + +while.body.i: ; preds = %for.cond, %while.body.i + %c.05.i = phi i32 [ %inc.i, %while.body.i ], [ 0, %for.cond ] + %i.addr.04.i = phi i32 [ %shr.i, %while.body.i ], [ %sub, %for.cond ] + %shr.i = ashr i32 %i.addr.04.i, 1 + %inc.i = add nsw i32 %c.05.i, 1 + %cmp.i = icmp sgt i32 %c.05.i, 5 + %tobool.not.i = icmp ult i32 %i.addr.04.i, 4 + %or.cond.i = select i1 %cmp.i, i1 true, i1 %tobool.not.i + br i1 %or.cond.i, label %h.exit, label %while.body.i + +h.exit: ; preds = %while.body.i + %inc.i.lcssa = phi i32 [ %inc.i, %while.body.i ] + %1 = trunc i32 %and to i8 + %2 = trunc i32 %inc.i.lcssa to i8 + %3 = sub i8 %1, %2 + %tobool.not = icmp eq i8 %3, 17 + %sub6 = add i16 %storemerge, -8 + br i1 %tobool.not, label %for.cond, label %if.then + +if.then: ; preds = %h.exit + %storemerge.lcssa = phi i16 [ %storemerge, %h.exit ] + %inc.lcssa = phi i32 [ %inc, %h.exit ] + %and.lcssa = phi i32 [ %and, %h.exit ] + %inc.i.lcssa.lcssa = phi i32 [ %inc.i.lcssa, %h.exit ] + store i16 %storemerge.lcssa, ptr @f, align 2 + store i32 %inc.lcssa, ptr @a, align 4 + store i32 %and.lcssa, ptr @d, align 4 + store i32 %inc.i.lcssa.lcssa, ptr @e, align 4 + %4 = load i8, ptr @g, align 1 + ret i8 %4 +}