llvm.org GIT mirror llvm / 342e0df
[SimplifyIndVar] Constant fold IV users This patch tries to transform cases like: for (unsigned i = 0; i < N; i += 2) { bool c0 = (i & 0x1) == 0; bool c1 = ((i + 1) & 0x1) == 1; } To for (unsigned i = 0; i < N; i += 2) { bool c0 = true; bool c1 = true; } This commit also update test/Transforms/IndVarSimplify/replace-srem-by-urem.ll to prevent constant folding. Differential Revision: https://reviews.llvm.org/D38272 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@314266 91177308-0d34-0410-b5e6-96231b3b80d8 Hongbin Zheng 2 years ago
3 changed file(s) with 78 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
3434
3535 STATISTIC(NumElimIdentity, "Number of IV identities eliminated");
3636 STATISTIC(NumElimOperand, "Number of IV operands folded into a use");
37 STATISTIC(NumFoldedUser, "Number of IV users folded into a constant");
3738 STATISTIC(NumElimRem , "Number of IV remainder operations eliminated");
3839 STATISTIC(
3940 NumSimplifiedSDiv,
7576 Value *foldIVUser(Instruction *UseInst, Instruction *IVOperand);
7677
7778 bool eliminateIdentitySCEV(Instruction *UseInst, Instruction *IVOperand);
79 bool foldConstantSCEV(Instruction *UseInst);
7880
7981 bool eliminateOverflowIntrinsic(CallInst *CI);
8082 bool eliminateIVUser(Instruction *UseInst, Instruction *IVOperand);
533535 return false;
534536 }
535537
538 /// Replace the UseInst with a constant if possible
539 bool SimplifyIndvar::foldConstantSCEV(Instruction *I) {
540 if (!SE->isSCEVable(I->getType()))
541 return false;
542
543 // Get the symbolic expression for this instruction.
544 const SCEV *S = SE->getSCEV(I);
545
546 const Loop *L = LI->getLoopFor(I->getParent());
547 S = SE->getSCEVAtScope(S, L);
548
549 if (auto *C = dyn_cast(S)) {
550 I->replaceAllUsesWith(C->getValue());
551 DEBUG(dbgs() << "INDVARS: Replace IV user: " << *I
552 << " with constant: " << *C << '\n');
553 ++NumFoldedUser;
554 Changed = true;
555 DeadInsts.emplace_back(I);
556 return true;
557 }
558
559 return false;
560 }
561
536562 /// Eliminate any operation that SCEV can prove is an identity function.
537563 bool SimplifyIndvar::eliminateIdentitySCEV(Instruction *UseInst,
538564 Instruction *IVOperand) {
740766 // Bypass back edges to avoid extra work.
741767 if (UseInst == CurrIV) continue;
742768
769 // Try to replace UseInst with a constant before any other simplifications
770 if (foldConstantSCEV(UseInst))
771 continue;
772
743773 Instruction *IVOperand = UseOper.second;
744774 for (unsigned N = 0; IVOperand; ++N) {
745775 assert(N <= Simplified.size() && "runaway iteration");
0 ; RUN: opt -indvars -S < %s | FileCheck %s
1
2 define void @test0(i32* %x) {
3 entry:
4 br label %for.inc
5
6 for.inc: ; preds = %for.inc, %entry
7 %i.01 = phi i32 [ 0, %entry ], [ %add, %for.inc ]
8 %and = and i32 %i.01, 3
9 %cmp1 = icmp eq i32 %and, 0
10 %cond = select i1 %cmp1, i32 0, i32 1
11 store i32 %cond, i32* %x, align 4
12 %add = add i32 %i.01, 4
13 %cmp = icmp ult i32 %add, 8
14 br i1 %cmp, label %for.inc, label %for.end
15
16 for.end: ; preds = %for.inc
17 ret void
18 }
19
20 ; Should fold the condition of the select into constant
21 ; CHECK-LABEL: void @test
22 ; CHECK: icmp eq i32 0, 0
23
24 define void @test1(i32* %a) {
25 entry:
26 br label %for.body
27
28 for.body: ; preds = %entry, %for.body
29 %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
30 %mul = mul nsw i32 %i.01, 64
31 %rem = srem i32 %mul, 8
32 %idxprom = sext i32 %rem to i64
33 %arrayidx = getelementptr inbounds i32, i32* %a, i64 %idxprom
34 store i32 %i.01, i32* %arrayidx, align 4
35 %inc = add nsw i32 %i.01, 1
36 %cmp = icmp slt i32 %inc, 64
37 br i1 %cmp, label %for.body, label %for.end
38
39 for.end: ; preds = %for.body
40 ret void
41 }
42
43 ; Should fold the rem since %mul is multiple of 8
44 ; CHECK-LABEL: @test1(
45 ; CHECK-NOT: rem
46 ; CHECK: sext i32 0 to i64
7070 for.body: ; preds = %entry, %for.body
7171 %i.01 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
7272 %mul = mul nsw i32 %i.01, 64
73 %rem = srem i32 %mul, 8
73 %rem = srem i32 %mul, 7
7474 ; CHECK: urem
7575 ; CHECK-NOT: srem
7676 %idxprom = sext i32 %rem to i64