llvm.org GIT mirror llvm / fa94b94
Optimize (x/C)*C to x if the division is exact. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@78811 91177308-0d34-0410-b5e6-96231b3b80d8 Dan Gohman 10 years ago
2 changed file(s) with 47 addition(s) and 1 deletion(s). Raw diff Collapse all Expand all
27002700 BO->getOpcode() == Instruction::SDiv)) {
27012701 Value *Op0BO = BO->getOperand(0), *Op1BO = BO->getOperand(1);
27022702
2703 // If the division is exact, X % Y is zero.
2704 if (SDivOperator *SDiv = dyn_cast(BO))
2705 if (SDiv->isExact()) {
2706 if (Op1BO == Op1)
2707 return ReplaceInstUsesWith(I, Op0BO);
2708 else
2709 return BinaryOperator::CreateNeg(Op0BO);
2710 }
2711
27032712 Instruction *Rem;
27042713 if (BO->getOpcode() == Instruction::UDiv)
27052714 Rem = BinaryOperator::CreateURem(Op0BO, Op1BO);
30593068 if (RHS->isAllOnesValue())
30603069 return BinaryOperator::CreateNeg(Op0);
30613070
3062 // sdiv X, C --> ashr X, log2(C)
3071 // sdiv X, C --> ashr X, log2(C)
30633072 if (cast(&I)->isExact() &&
30643073 RHS->getValue().isNonNegative() &&
30653074 RHS->getValue().isPowerOf2()) {
1212 %y = sdiv exact i32 %x, 8
1313 ret i32 %y
1414 }
15
16 ; CHECK: i32 @a0
17 ; CHECK: %y = srem i32 %x, 3
18 ; CHECK: %z = sub i32 %x, %y
19 ; CHECK: ret i32 %z
20 define i32 @a0(i32 %x) {
21 %y = sdiv i32 %x, 3
22 %z = mul i32 %y, 3
23 ret i32 %z
24 }
25
26 ; CHECK: i32 @b0
27 ; CHECK: ret i32 %x
28 define i32 @b0(i32 %x) {
29 %y = sdiv exact i32 %x, 3
30 %z = mul i32 %y, 3
31 ret i32 %z
32 }
33
34 ; CHECK: i32 @a1
35 ; CHECK: %y = srem i32 %x, 3
36 ; CHECK: %z = sub i32 %y, %x
37 ; CHECK: ret i32 %z
38 define i32 @a1(i32 %x) {
39 %y = sdiv i32 %x, 3
40 %z = mul i32 %y, -3
41 ret i32 %z
42 }
43
44 ; CHECK: i32 @b1
45 ; CHECK: %z = sub i32 0, %x
46 ; CHECK: ret i32 %z
47 define i32 @b1(i32 %x) {
48 %y = sdiv exact i32 %x, 3
49 %z = mul i32 %y, -3
50 ret i32 %z
51 }