diff options
author | Chris Lattner <sabre@nondot.org> | 2008-04-19 21:58:19 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2008-04-19 21:58:19 +0000 |
commit | 1c14c297460e0a6480bab989c0ade346288bbfd2 (patch) | |
tree | cbfa03122b461b9ad864c17e5716ab89fa69231e | |
parent | 61783d73223eed373fdcf1e4bda29978323f9e54 (diff) | |
download | external_llvm-1c14c297460e0a6480bab989c0ade346288bbfd2.zip external_llvm-1c14c297460e0a6480bab989c0ade346288bbfd2.tar.gz external_llvm-1c14c297460e0a6480bab989c0ade346288bbfd2.tar.bz2 |
refactor handling of symbolic constant folding, picking up
a few new cases( see Integer/a1.ll), but not anything that
would happen in practice.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@49965 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | lib/VMCore/ConstantFold.cpp | 124 | ||||
-rw-r--r-- | test/Integer/a1.ll.out | 8 |
2 files changed, 66 insertions, 66 deletions
diff --git a/lib/VMCore/ConstantFold.cpp b/lib/VMCore/ConstantFold.cpp index 64fa676..c15ce96 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 0957c75..93ca11a 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] |