llvm.org GIT mirror llvm / 5697690
Revert "[SCEVExpand] do not hoist divisions by zero (PR30935)" Reverts r289412. It caused an OOB PHI operand access in instcombine when ASan is enabled. Reduction in progress. Also reverts "[SCEVExpander] Add a test case related to r289412" git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289453 91177308-0d34-0410-b5e6-96231b3b80d8 Reid Kleckner 2 years ago
4 changed file(s) with 38 addition(s) and 264 deletion(s). Raw diff Collapse all Expand all
21292129 }
21302130
21312131 // Okay, check to see if the same value occurs in the operand list more than
2132 // once. If so, merge them together into a multiply expression. Since we
2132 // once. If so, merge them together into an multiply expression. Since we
21332133 // sorted the list, these values are required to be adjacent.
21342134 Type *Ty = Ops[0]->getType();
21352135 bool FoundMatch = false;
165165 return ReuseOrCreateCast(I, Ty, Op, IP);
166166 }
167167
168 // Return true when S may contain the value zero.
169 static bool mayBeValueZero(Value *V) {
170 if (ConstantInt *C = dyn_cast(V))
171 if (!C->isZero())
172 return false;
173
174 // All other expressions may have a zero value.
175 return true;
176 }
177
178168 /// InsertBinop - Insert the specified binary operator, doing a small amount
179169 /// of work to avoid inserting an obviously redundant operation.
180170 Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
207197 DebugLoc Loc = Builder.GetInsertPoint()->getDebugLoc();
208198 SCEVInsertPointGuard Guard(Builder, this);
209199
210 // Only move the insertion point up when it is not a division by zero.
211 if (Opcode != Instruction::UDiv || !mayBeValueZero(RHS)) {
212 // Move the insertion point out of as many loops as we can.
213 while (const Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock())) {
214 if (!L->isLoopInvariant(LHS) || !L->isLoopInvariant(RHS)) break;
215 BasicBlock *Preheader = L->getLoopPreheader();
216 if (!Preheader) break;
217
218 // Ok, move up a level.
219 Builder.SetInsertPoint(Preheader->getTerminator());
220 }
200 // Move the insertion point out of as many loops as we can.
201 while (const Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock())) {
202 if (!L->isLoopInvariant(LHS) || !L->isLoopInvariant(RHS)) break;
203 BasicBlock *Preheader = L->getLoopPreheader();
204 if (!Preheader) break;
205
206 // Ok, move up a level.
207 Builder.SetInsertPoint(Preheader->getTerminator());
221208 }
222209
223210 // If we haven't found this binop, insert it.
16781665 // Compute an insertion point for this SCEV object. Hoist the instructions
16791666 // as far out in the loop nest as possible.
16801667 Instruction *InsertPt = &*Builder.GetInsertPoint();
1681 bool SafeToHoist = !SCEVExprContains(S, [](const SCEV *S) {
1682 if (const auto *D = dyn_cast(S)) {
1683 if (const auto *SC = dyn_cast(D->getRHS()))
1684 // Division by non-zero constants can be hoisted.
1685 return SC->getValue()->isZero();
1686
1687 // All other divisions should not be moved as they may be divisions by
1688 // zero and should be kept within the conditions of the surrounding
1689 // loops that guard their execution (see PR30935.)
1690 return true;
1691 }
1692 return false;
1693 });
1694 if (SafeToHoist) {
1695 for (Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock());;
1696 L = L->getParentLoop())
1697 if (SE.isLoopInvariant(S, L)) {
1698 if (!L) break;
1699 if (BasicBlock *Preheader = L->getLoopPreheader())
1700 InsertPt = Preheader->getTerminator();
1701 else {
1702 // LSR sets the insertion point for AddRec start/step values to the
1703 // block start to simplify value reuse, even though it's an invalid
1704 // position. SCEVExpander must correct for this in all cases.
1705 InsertPt = &*L->getHeader()->getFirstInsertionPt();
1706 }
1707 } else {
1708 // If the SCEV is computable at this level, insert it into the header
1709 // after the PHIs (and after any other instructions that we've inserted
1710 // there) so that it is guaranteed to dominate any user inside the loop.
1711 if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L))
1712 InsertPt = &*L->getHeader()->getFirstInsertionPt();
1713 while (InsertPt->getIterator() != Builder.GetInsertPoint() &&
1714 (isInsertedInstruction(InsertPt) ||
1715 isa(InsertPt))) {
1716 InsertPt = &*std::next(InsertPt->getIterator());
1717 }
1718 break;
1719 }
1720 }
1668 for (Loop *L = SE.LI.getLoopFor(Builder.GetInsertBlock());;
1669 L = L->getParentLoop())
1670 if (SE.isLoopInvariant(S, L)) {
1671 if (!L) break;
1672 if (BasicBlock *Preheader = L->getLoopPreheader())
1673 InsertPt = Preheader->getTerminator();
1674 else {
1675 // LSR sets the insertion point for AddRec start/step values to the
1676 // block start to simplify value reuse, even though it's an invalid
1677 // position. SCEVExpander must correct for this in all cases.
1678 InsertPt = &*L->getHeader()->getFirstInsertionPt();
1679 }
1680 } else {
1681 // If the SCEV is computable at this level, insert it into the header
1682 // after the PHIs (and after any other instructions that we've inserted
1683 // there) so that it is guaranteed to dominate any user inside the loop.
1684 if (L && SE.hasComputableLoopEvolution(S, L) && !PostIncLoops.count(L))
1685 InsertPt = &*L->getHeader()->getFirstInsertionPt();
1686 while (InsertPt->getIterator() != Builder.GetInsertPoint() &&
1687 (isInsertedInstruction(InsertPt) ||
1688 isa(InsertPt))) {
1689 InsertPt = &*std::next(InsertPt->getIterator());
1690 }
1691 break;
1692 }
17211693
17221694 // Check to see if we already expanded this here.
17231695 auto I = InsertedExpressions.find(std::make_pair(S, InsertPt));
+0
-94
test/Transforms/LoopIdiom/pr30935.ll less more
None ; RUN: opt -loop-idiom -S < %s | FileCheck %s
1
2 ; CHECK-LABEL: define i32 @main(
3 ; CHECK: udiv
4 ; CHECK-NOT: udiv
5 ; CHECK: call void @llvm.memset.p0i8.i64
6
7 @a = common local_unnamed_addr global [4 x i8] zeroinitializer, align 1
8 @b = common local_unnamed_addr global i32 0, align 4
9 @c = common local_unnamed_addr global i32 0, align 4
10 @d = common local_unnamed_addr global i32 0, align 4
11 @e = common local_unnamed_addr global i32 0, align 4
12 @f = common local_unnamed_addr global i32 0, align 4
13 @g = common local_unnamed_addr global i32 0, align 4
14 @h = common local_unnamed_addr global i64 0, align 8
15
16
17 define i32 @main() local_unnamed_addr #0 {
18 entry:
19 %0 = load i32, i32* @e, align 4
20 %tobool19 = icmp eq i32 %0, 0
21 %1 = load i32, i32* @c, align 4
22 %cmp10 = icmp eq i32 %1, 0
23 %2 = load i32, i32* @g, align 4
24 %3 = load i32, i32* @b, align 4
25 %tobool = icmp eq i32 %0, 0
26 br label %for.cond
27
28 for.cond.loopexit: ; preds = %for.inc14
29 br label %for.cond.backedge
30
31 for.cond: ; preds = %for.cond.backedge, %entry
32 %.pr = load i32, i32* @f, align 4
33 %cmp20 = icmp eq i32 %.pr, 0
34 br i1 %cmp20, label %for.cond2.preheader.preheader, label %for.cond.backedge
35
36 for.cond.backedge: ; preds = %for.cond, %for.cond.loopexit
37 br label %for.cond
38
39 for.cond2.preheader.preheader: ; preds = %for.cond
40 br label %for.cond2.preheader
41
42 for.cond2.preheader: ; preds = %for.cond2.preheader.preheader, %for.inc14
43 br i1 %tobool19, label %for.cond9, label %for.body3.lr.ph
44
45 for.body3.lr.ph: ; preds = %for.cond2.preheader
46 %div = udiv i32 %2, %3
47 %conv = zext i32 %div to i64
48 br label %for.body3
49
50 for.cond4.for.cond2.loopexit_crit_edge: ; preds = %for.body6
51 store i32 0, i32* @d, align 4
52 br label %for.cond2.loopexit
53
54 for.cond2.loopexit: ; preds = %for.cond4.for.cond2.loopexit_crit_edge, %for.body3
55 br i1 %tobool, label %for.cond2.for.cond9_crit_edge, label %for.body3
56
57 for.body3: ; preds = %for.body3.lr.ph, %for.cond2.loopexit
58 %.pr17 = load i32, i32* @d, align 4
59 %tobool518 = icmp eq i32 %.pr17, 0
60 br i1 %tobool518, label %for.cond2.loopexit, label %for.body6.preheader
61
62 for.body6.preheader: ; preds = %for.body3
63 %4 = zext i32 %.pr17 to i64
64 br label %for.body6
65
66 for.body6: ; preds = %for.body6.preheader, %for.body6
67 %indvars.iv = phi i64 [ %4, %for.body6.preheader ], [ %indvars.iv.next, %for.body6 ]
68 %add = add nuw nsw i64 %conv, %indvars.iv
69 %arrayidx = getelementptr inbounds [4 x i8], [4 x i8]* @a, i64 0, i64 %add
70 store i8 1, i8* %arrayidx, align 1
71 %5 = trunc i64 %indvars.iv to i32
72 %inc = add i32 %5, 1
73 %tobool5 = icmp eq i32 %inc, 0
74 %indvars.iv.next = add nuw nsw i64 %indvars.iv, 1
75 br i1 %tobool5, label %for.cond4.for.cond2.loopexit_crit_edge, label %for.body6
76
77 for.cond2.for.cond9_crit_edge: ; preds = %for.cond2.loopexit
78 store i64 %conv, i64* @h, align 8
79 br label %for.cond9
80
81 for.cond9: ; preds = %for.cond2.for.cond9_crit_edge, %for.cond2.preheader
82 br i1 %cmp10, label %for.body12, label %for.inc14
83
84 for.body12: ; preds = %for.cond9
85 ret i32 0
86
87 for.inc14: ; preds = %for.cond9
88 %6 = load i32, i32* @f, align 4
89 %inc15 = add i32 %6, 1
90 store i32 %inc15, i32* @f, align 4
91 %cmp = icmp eq i32 %inc15, 0
92 br i1 %cmp, label %for.cond2.preheader, label %for.cond.loopexit
93 }
5050 return ScalarEvolution(F, TLI, *AC, *DT, *LI);
5151 }
5252
53 void runSCEVTest(Module &M, StringRef FuncName,
54 function_ref
55 LoopInfo &LI, ScalarEvolution &SE)>
56 Test) {
53 void runWithFunctionAndSE(
54 Module &M, StringRef FuncName,
55 function_ref Test) {
5756 auto *F = M.getFunction(FuncName);
5857 ASSERT_NE(F, nullptr) << "Could not find " << FuncName;
5958 ScalarEvolution SE = buildSE(*F);
60 Test(*F, *DT, *LI, SE);
61 }
62
63 void runWithFunctionAndSE(
64 Module &M, StringRef FuncName,
65 function_ref Test) {
66 runSCEVTest(M, FuncName, [&](Function &F, DominatorTree &DT, LoopInfo &LI,
67 ScalarEvolution &SE) { Test(F, SE); });
59 Test(*F, SE);
6860 }
6961 };
7062
356348 llvm_unreachable("Expected to find instruction!");
357349 }
358350
359 static Argument *getArgByName(Function &F, StringRef Name) {
360 for (auto &A : F.args())
361 if (A.getName() == Name)
362 return &A;
363 llvm_unreachable("Expected to find argument!");
364 }
365
366351 TEST_F(ScalarEvolutionsTest, CommutativeExprOperandOrder) {
367352 LLVMContext C;
368353 SMDiagnostic Err;
546531 EXPECT_NE(nullptr, SE.getSCEV(Acc[0]));
547532 }
548533
549 TEST_F(ScalarEvolutionsTest, BadHoistingSCEVExpander_PR30942) {
550 LLVMContext C;
551 SMDiagnostic Err;
552 std::unique_ptr M = parseAssemblyString(
553 "target datalayout = \"e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128\" "
554 " "
555 "define void @f_1(i32 %x, i32 %y, i32 %n, i1* %cond_buf) "
556 " local_unnamed_addr { "
557 "entry: "
558 " %entrycond = icmp sgt i32 %n, 0 "
559 " br i1 %entrycond, label %loop.ph, label %for.end "
560 " "
561 "loop.ph: "
562 " br label %loop "
563 " "
564 "loop: "
565 " %iv1 = phi i32 [ %iv1.inc, %right ], [ 0, %loop.ph ] "
566 " %iv1.inc = add nuw nsw i32 %iv1, 1 "
567 " %cond = load volatile i1, i1* %cond_buf "
568 " br i1 %cond, label %left, label %right "
569 " "
570 "left: "
571 " %div = udiv i32 %x, %y "
572 " br label %right "
573 " "
574 "right: "
575 " %exitcond = icmp eq i32 %iv1.inc, %n "
576 " br i1 %exitcond, label %for.end.loopexit, label %loop "
577 " "
578 "for.end.loopexit: "
579 " br label %for.end "
580 " "
581 "for.end: "
582 " ret void "
583 "} ",
584 Err, C);
585
586 assert(M && "Could not parse module?");
587 assert(!verifyModule(*M) && "Must have been well formed!");
588
589 runSCEVTest(*M, "f_1", [&](Function &F, DominatorTree &DT, LoopInfo &LI,
590 ScalarEvolution &SE) {
591 SCEVExpander Expander(SE, M->getDataLayout(), "unittests");
592 auto *DivInst = getInstructionByName(F, "div");
593
594 {
595 auto *DivSCEV = SE.getSCEV(DivInst);
596 auto *DivExpansion = Expander.expandCodeFor(
597 DivSCEV, DivSCEV->getType(), DivInst->getParent()->getTerminator());
598 auto *DivExpansionInst = dyn_cast(DivExpansion);
599 ASSERT_NE(DivExpansionInst, nullptr);
600 EXPECT_EQ(DivInst->getParent(), DivExpansionInst->getParent());
601 }
602
603 {
604 auto *ArgY = getArgByName(F, "y");
605 auto *DivFromScratchSCEV =
606 SE.getUDivExpr(SE.getOne(ArgY->getType()), SE.getSCEV(ArgY));
607
608 auto *DivFromScratchExpansion = Expander.expandCodeFor(
609 DivFromScratchSCEV, DivFromScratchSCEV->getType(),
610 DivInst->getParent()->getTerminator());
611 auto *DivFromScratchExpansionInst =
612 dyn_cast(DivFromScratchExpansion);
613 ASSERT_NE(DivFromScratchExpansionInst, nullptr);
614 EXPECT_EQ(DivInst->getParent(), DivFromScratchExpansionInst->getParent());
615 }
616
617 {
618 auto *ArgY = getArgByName(F, "y");
619 auto *One = SE.getOne(ArgY->getType());
620 auto *DivFromScratchSCEV = SE.getUDivExpr(One, SE.getSCEV(ArgY));
621 auto *L = LI.getLoopFor(DivInst->getParent());
622 auto *ARFromScratchSCEV =
623 SE.getAddRecExpr(DivFromScratchSCEV, One, L, SCEV::FlagAnyWrap);
624
625 Expander.disableCanonicalMode();
626
627 auto *ARFromScratchExpansion = Expander.expandCodeFor(
628 ARFromScratchSCEV, ARFromScratchSCEV->getType(),
629 DivInst->getParent()->getTerminator());
630 auto *ARFromScratchExpansionInst =
631 dyn_cast(ARFromScratchExpansion);
632 ASSERT_NE(ARFromScratchExpansionInst, nullptr);
633 ASSERT_FALSE(verifyFunction(F));
634 }
635 });
636 }
637
638534 } // end anonymous namespace
639535 } // end namespace llvm