[llvm-commits] [llvm] r49965 - in /llvm/trunk: lib/VMCore/ConstantFold.cpp test/Integer/a1.ll.out
Chris Lattner
sabre at nondot.org
Sat Apr 19 14:58:20 PDT 2008
Author: lattner
Date: Sat Apr 19 16:58:19 2008
New Revision: 49965
URL: http://llvm.org/viewvc/llvm-project?rev=49965&view=rev
Log:
refactor handling of symbolic constant folding, picking up
a few new cases( see Integer/a1.ll), but not anything that
would happen in practice.
Modified:
llvm/trunk/lib/VMCore/ConstantFold.cpp
llvm/trunk/test/Integer/a1.ll.out
Modified: llvm/trunk/lib/VMCore/ConstantFold.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/VMCore/ConstantFold.cpp?rev=49965&r1=49964&r2=49965&view=diff
==============================================================================
--- llvm/trunk/lib/VMCore/ConstantFold.cpp (original)
+++ llvm/trunk/lib/VMCore/ConstantFold.cpp Sat Apr 19 16:58:19 2008
@@ -519,56 +519,50 @@
}
}
- 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);
- }
- }
- if (CE1->isCast() && isa<GlobalValue>(CE1->getOperand(0))) {
+ // 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->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 @@
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.
Modified: llvm/trunk/test/Integer/a1.ll.out
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Integer/a1.ll.out?rev=49965&r1=49964&r2=49965&view=diff
==============================================================================
--- llvm/trunk/test/Integer/a1.ll.out (original)
+++ llvm/trunk/test/Integer/a1.ll.out Sat Apr 19 16:58:19 2008
@@ -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]
- at o = constant i1 sdiv (i1 true, i1 true) ; <i1*> [#uses=0]
- at p = constant i1 sdiv (i1 true, i1 true) ; <i1*> [#uses=0]
+ at o = constant i1 true ; <i1*> [#uses=0]
+ at p = constant i1 true ; <i1*> [#uses=0]
@q = constant i1 true ; <i1*> [#uses=0]
@r = constant i1 true ; <i1*> [#uses=0]
- at s = constant i1 srem (i1 true, i1 true) ; <i1*> [#uses=0]
+ at s = constant i1 false ; <i1*> [#uses=0]
@t = constant i1 false ; <i1*> [#uses=0]
- at u = constant i1 srem (i1 true, i1 true) ; <i1*> [#uses=0]
+ at u = constant i1 false ; <i1*> [#uses=0]
More information about the llvm-commits
mailing list