summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/VMCore/ConstantFold.cpp124
-rw-r--r--test/Integer/a1.ll.out8
2 files changed, 66 insertions, 66 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp
index 64fa67645b..c15ce96959 100644
--- a/lib/VMCore/ConstantFold.cpp
+++ b/lib/VMCore/ConstantFold.cpp
@@ -519,56 +519,50 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
}
}
- if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
- if (isa<ConstantExpr>(C2)) {
- // There are many possible foldings we could do here. We should probably
- // at least fold add of a pointer with an integer into the appropriate
- // getelementptr. This will improve alias analysis a bit.
- } else {
- // Just implement a couple of simple identities.
- switch (Opcode) {
- case Instruction::Add:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X + 0 == X
- break;
- case Instruction::Sub:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X - 0 == X
- break;
- case Instruction::Mul:
- if (C2->isNullValue()) return const_cast<Constant*>(C2); // X * 0 == 0
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->equalsInt(1))
- return const_cast<Constant*>(C1); // X * 1 == X
- break;
- case Instruction::UDiv:
- case Instruction::SDiv:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->equalsInt(1))
- return const_cast<Constant*>(C1); // X / 1 == X
- break;
- case Instruction::URem:
- case Instruction::SRem:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->equalsInt(1))
- return Constant::getNullValue(CI->getType()); // X % 1 == 0
- break;
- case Instruction::And:
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) {
- if (CI->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
- if (CI->isAllOnesValue())
- return const_cast<Constant*>(C1); // X & -1 == X
-
- // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
- if (CE1->getOpcode() == Instruction::ZExt) {
- APInt PossiblySetBits
- = cast<IntegerType>(CE1->getOperand(0)->getType())->getMask();
- PossiblySetBits.zext(C1->getType()->getPrimitiveSizeInBits());
- if ((PossiblySetBits & CI->getValue()) == PossiblySetBits)
- return const_cast<Constant*>(C1);
- }
+ // Handle simplifications of the RHS when a constant int.
+ if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
+ switch (Opcode) {
+ case Instruction::Add:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X + 0 == X
+ break;
+ case Instruction::Sub:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X - 0 == X
+ break;
+ case Instruction::Mul:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C2); // X * 0 == 0
+ if (CI2->equalsInt(1))
+ return const_cast<Constant*>(C1); // X * 1 == X
+ break;
+ case Instruction::UDiv:
+ case Instruction::SDiv:
+ if (CI2->equalsInt(1))
+ return const_cast<Constant*>(C1); // X / 1 == X
+ break;
+ case Instruction::URem:
+ case Instruction::SRem:
+ if (CI2->equalsInt(1))
+ return Constant::getNullValue(CI2->getType()); // X % 1 == 0
+ break;
+ case Instruction::And:
+ if (CI2->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
+ if (CI2->isAllOnesValue())
+ return const_cast<Constant*>(C1); // X & -1 == X
+
+ // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
+ if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
+ if (CE1->getOpcode() == Instruction::ZExt) {
+ unsigned DstWidth = CI2->getType()->getBitWidth();
+ unsigned SrcWidth =
+ CE1->getOperand(0)->getType()->getPrimitiveSizeInBits();
+ APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth));
+ if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits)
+ return const_cast<Constant*>(C1);
}
- if (CE1->isCast() && isa<GlobalValue>(CE1->getOperand(0))) {
+
+ if (CE1->getOpcode() == Instruction::PtrToInt &&
+ isa<GlobalValue>(CE1->getOperand(0))) {
GlobalValue *CPR = cast<GlobalValue>(CE1->getOperand(0));
-
+
// Functions are at least 4-byte aligned. If and'ing the address of a
// function with a constant < 4, fold it to zero.
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
@@ -576,24 +570,30 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
isa<Function>(CPR))
return Constant::getNullValue(CI->getType());
}
- break;
- case Instruction::Or:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X | 0 == X
- if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
- if (CI->isAllOnesValue())
- return const_cast<Constant*>(C2); // X | -1 == -1
- break;
- case Instruction::Xor:
- if (C2->isNullValue()) return const_cast<Constant*>(C1); // X ^ 0 == X
- break;
- case Instruction::AShr:
- // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
+ }
+ break;
+ case Instruction::Or:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X | 0 == X
+ if (CI2->isAllOnesValue())
+ return const_cast<Constant*>(C2); // X | -1 == -1
+ break;
+ case Instruction::Xor:
+ if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X ^ 0 == X
+ break;
+ case Instruction::AShr:
+ // ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2
+ if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1))
if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero.
return ConstantExpr::getLShr(const_cast<Constant*>(C1),
const_cast<Constant*>(C2));
- break;
- }
+ break;
}
+ }
+
+ if (isa<ConstantExpr>(C1)) {
+ // There are many possible foldings we could do here. We should probably
+ // at least fold add of a pointer with an integer into the appropriate
+ // getelementptr. This will improve alias analysis a bit.
} else if (isa<ConstantExpr>(C2)) {
// If C2 is a constant expr and C1 isn't, flop them around and fold the
// other way if possible.
diff --git a/test/Integer/a1.ll.out b/test/Integer/a1.ll.out
index 0957c755b9..93ca11acd3 100644
--- a/test/Integer/a1.ll.out
+++ b/test/Integer/a1.ll.out
@@ -10,10 +10,10 @@
@j = constant i1 undef ; <i1*> [#uses=0]
@m = constant i1 undef ; <i1*> [#uses=0]
@n = constant i1 true ; <i1*> [#uses=0]
-@o = constant i1 sdiv (i1 true, i1 true) ; <i1*> [#uses=0]
-@p = constant i1 sdiv (i1 true, i1 true) ; <i1*> [#uses=0]
+@o = constant i1 true ; <i1*> [#uses=0]
+@p = constant i1 true ; <i1*> [#uses=0]
@q = constant i1 true ; <i1*> [#uses=0]
@r = constant i1 true ; <i1*> [#uses=0]
-@s = constant i1 srem (i1 true, i1 true) ; <i1*> [#uses=0]
+@s = constant i1 false ; <i1*> [#uses=0]
@t = constant i1 false ; <i1*> [#uses=0]
-@u = constant i1 srem (i1 true, i1 true) ; <i1*> [#uses=0]
+@u = constant i1 false ; <i1*> [#uses=0]