llvm.org GIT mirror llvm / b226b5d
[SCEVExpand] do not hoist divisions by zero (PR30935) SCEVExpand computes the insertion point for the components of a SCEV to be code generated. When it comes to generating code for a division, SCEVexpand would not be able to check (at compilation time) all the conditions necessary to avoid a division by zero. The patch disables hoisting of expressions containing divisions by anything other than non-zero constants in order to avoid hoisting these expressions past conditions that should hold before doing the division. The patch passes check-all on x86_64-linux. Differential Revision: https://reviews.llvm.org/D27216 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@289412 91177308-0d34-0410-b5e6-96231b3b80d8 Sebastian Pop 2 years ago
4 changed file(s) with 232 addition(s) and 34 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 an multiply expression. Since we
2132 // once. If so, merge them together into a 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
168178 /// InsertBinop - Insert the specified binary operator, doing a small amount
169179 /// of work to avoid inserting an obviously redundant operation.
170180 Value *SCEVExpander::InsertBinop(Instruction::BinaryOps Opcode,
197207 DebugLoc Loc = Builder.GetInsertPoint()->getDebugLoc();
198208 SCEVInsertPointGuard Guard(Builder, this);
199209
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());
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 }
208221 }
209222
210223 // If we haven't found this binop, insert it.
16651678 // Compute an insertion point for this SCEV object. Hoist the instructions
16661679 // as far out in the loop nest as possible.
16671680 Instruction *InsertPt = &*Builder.GetInsertPoint();
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 }
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 }
16931721
16941722 // Check to see if we already expanded this here.
16951723 auto I = InsertedExpressions.find(std::make_pair(S, InsertPt));
0 ; 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 }
348348 llvm_unreachable("Expected to find instruction!");
349349 }
350350
351 static Argument *getArgByName(Function &F, StringRef Name) {
352 for (auto &A : F.args())
353 if (A.getName() == Name)
354 return &A;
355 llvm_unreachable("Expected to find argument!");
356 }
357
351358 TEST_F(ScalarEvolutionsTest, CommutativeExprOperandOrder) {
352359 LLVMContext C;
353360 SMDiagnostic Err;
531538 EXPECT_NE(nullptr, SE.getSCEV(Acc[0]));
532539 }
533540
541 TEST_F(ScalarEvolutionsTest, BadHoistingSCEVExpander_PR30942) {
542 LLVMContext C;
543 SMDiagnostic Err;
544 std::unique_ptr M = parseAssemblyString(
545 "target datalayout = \"e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128\" "
546 " "
547 "define void @f_1(i32 %x, i32 %y, i32 %n, i1* %cond_buf) "
548 " local_unnamed_addr { "
549 "entry: "
550 " %entrycond = icmp sgt i32 %n, 0 "
551 " br i1 %entrycond, label %loop.ph, label %for.end "
552 " "
553 "loop.ph: "
554 " br label %loop "
555 " "
556 "loop: "
557 " %iv1 = phi i32 [ %iv1.inc, %right ], [ 0, %loop.ph ] "
558 " %iv1.inc = add nuw nsw i32 %iv1, 1 "
559 " %cond = load volatile i1, i1* %cond_buf "
560 " br i1 %cond, label %left, label %right "
561 " "
562 "left: "
563 " %div = udiv i32 %x, %y "
564 " br label %right "
565 " "
566 "right: "
567 " %exitcond = icmp eq i32 %iv1.inc, %n "
568 " br i1 %exitcond, label %for.end.loopexit, label %loop "
569 " "
570 "for.end.loopexit: "
571 " br label %for.end "
572 " "
573 "for.end: "
574 " ret void "
575 "} ",
576 Err, C);
577
578 assert(M && "Could not parse module?");
579 assert(!verifyModule(*M) && "Must have been well formed!");
580
581 runWithFunctionAndSE(*M, "f_1", [&](Function &F, ScalarEvolution &SE) {
582 SCEVExpander Expander(SE, M->getDataLayout(), "unittests");
583 auto *DivInst = getInstructionByName(F, "div");
584
585 {
586 auto *DivSCEV = SE.getSCEV(DivInst);
587 auto *DivExpansion = Expander.expandCodeFor(
588 DivSCEV, DivSCEV->getType(), DivInst->getParent()->getTerminator());
589 auto *DivExpansionInst = dyn_cast(DivExpansion);
590 ASSERT_NE(DivExpansionInst, nullptr);
591 EXPECT_EQ(DivInst->getParent(), DivExpansionInst->getParent());
592 }
593
594 {
595 auto *ArgY = getArgByName(F, "y");
596 auto *DivFromScratchSCEV =
597 SE.getUDivExpr(SE.getOne(ArgY->getType()), SE.getSCEV(ArgY));
598
599 auto *DivFromScratchExpansion = Expander.expandCodeFor(
600 DivFromScratchSCEV, DivFromScratchSCEV->getType(),
601 DivInst->getParent()->getTerminator());
602 auto *DivFromScratchExpansionInst =
603 dyn_cast(DivFromScratchExpansion);
604 ASSERT_NE(DivFromScratchExpansionInst, nullptr);
605 EXPECT_EQ(DivInst->getParent(), DivFromScratchExpansionInst->getParent());
606 }
607 });
608 }
609
534610 } // end anonymous namespace
535611 } // end namespace llvm