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
This commit is contained in:
Chris Lattner 2008-04-19 21:58:19 +00:00
parent 61783d7322
commit 1c14c29746
2 changed files with 66 additions and 66 deletions

View File

@ -519,56 +519,50 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
} }
} }
if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) { // Handle simplifications of the RHS when a constant int.
if (isa<ConstantExpr>(C2)) { if (const ConstantInt *CI2 = dyn_cast<ConstantInt>(C2)) {
// There are many possible foldings we could do here. We should probably switch (Opcode) {
// at least fold add of a pointer with an integer into the appropriate case Instruction::Add:
// getelementptr. This will improve alias analysis a bit. if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X + 0 == X
} else { break;
// Just implement a couple of simple identities. case Instruction::Sub:
switch (Opcode) { if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X - 0 == X
case Instruction::Add: break;
if (C2->isNullValue()) return const_cast<Constant*>(C1); // X + 0 == X case Instruction::Mul:
break; if (CI2->equalsInt(0)) return const_cast<Constant*>(C2); // X * 0 == 0
case Instruction::Sub: if (CI2->equalsInt(1))
if (C2->isNullValue()) return const_cast<Constant*>(C1); // X - 0 == X return const_cast<Constant*>(C1); // X * 1 == X
break; break;
case Instruction::Mul: case Instruction::UDiv:
if (C2->isNullValue()) return const_cast<Constant*>(C2); // X * 0 == 0 case Instruction::SDiv:
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) if (CI2->equalsInt(1))
if (CI->equalsInt(1)) return const_cast<Constant*>(C1); // X / 1 == X
return const_cast<Constant*>(C1); // X * 1 == X break;
break; case Instruction::URem:
case Instruction::UDiv: case Instruction::SRem:
case Instruction::SDiv: if (CI2->equalsInt(1))
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) return Constant::getNullValue(CI2->getType()); // X % 1 == 0
if (CI->equalsInt(1)) break;
return const_cast<Constant*>(C1); // X / 1 == X case Instruction::And:
break; if (CI2->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0
case Instruction::URem: if (CI2->isAllOnesValue())
case Instruction::SRem: return const_cast<Constant*>(C1); // X & -1 == X
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
if (CI->equalsInt(1)) // (zext i32 to i64) & 4294967295 -> (zext i32 to i64)
return Constant::getNullValue(CI->getType()); // X % 1 == 0 if (const ConstantExpr *CE1 = dyn_cast<ConstantExpr>(C1)) {
break; if (CE1->getOpcode() == Instruction::ZExt) {
case Instruction::And: unsigned DstWidth = CI2->getType()->getBitWidth();
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) { unsigned SrcWidth =
if (CI->isZero()) return const_cast<Constant*>(C2); // X & 0 == 0 CE1->getOperand(0)->getType()->getPrimitiveSizeInBits();
if (CI->isAllOnesValue()) APInt PossiblySetBits(APInt::getLowBitsSet(DstWidth, SrcWidth));
return const_cast<Constant*>(C1); // X & -1 == X if ((PossiblySetBits & CI2->getValue()) == PossiblySetBits)
return const_cast<Constant*>(C1);
// (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))) {
if (CE1->getOpcode() == Instruction::PtrToInt &&
isa<GlobalValue>(CE1->getOperand(0))) {
GlobalValue *CPR = cast<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 // Functions are at least 4-byte aligned. If and'ing the address of a
// function with a constant < 4, fold it to zero. // function with a constant < 4, fold it to zero.
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2))
@ -576,24 +570,30 @@ Constant *llvm::ConstantFoldBinaryInstruction(unsigned Opcode,
isa<Function>(CPR)) isa<Function>(CPR))
return Constant::getNullValue(CI->getType()); return Constant::getNullValue(CI->getType());
} }
break; }
case Instruction::Or: break;
if (C2->isNullValue()) return const_cast<Constant*>(C1); // X | 0 == X case Instruction::Or:
if (const ConstantInt *CI = dyn_cast<ConstantInt>(C2)) if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X | 0 == X
if (CI->isAllOnesValue()) if (CI2->isAllOnesValue())
return const_cast<Constant*>(C2); // X | -1 == -1 return const_cast<Constant*>(C2); // X | -1 == -1
break; break;
case Instruction::Xor: case Instruction::Xor:
if (C2->isNullValue()) return const_cast<Constant*>(C1); // X ^ 0 == X if (CI2->equalsInt(0)) return const_cast<Constant*>(C1); // X ^ 0 == X
break; break;
case Instruction::AShr: case Instruction::AShr:
// ashr (zext C to Ty), C2 -> lshr (zext C, CSA), C2 // 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. if (CE1->getOpcode() == Instruction::ZExt) // Top bits known zero.
return ConstantExpr::getLShr(const_cast<Constant*>(C1), return ConstantExpr::getLShr(const_cast<Constant*>(C1),
const_cast<Constant*>(C2)); 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)) { } else if (isa<ConstantExpr>(C2)) {
// If C2 is a constant expr and C1 isn't, flop them around and fold the // If C2 is a constant expr and C1 isn't, flop them around and fold the
// other way if possible. // other way if possible.

View File

@ -10,10 +10,10 @@
@j = constant i1 undef ; <i1*> [#uses=0] @j = constant i1 undef ; <i1*> [#uses=0]
@m = constant i1 undef ; <i1*> [#uses=0] @m = constant i1 undef ; <i1*> [#uses=0]
@n = constant i1 true ; <i1*> [#uses=0] @n = constant i1 true ; <i1*> [#uses=0]
@o = constant i1 sdiv (i1 true, i1 true) ; <i1*> [#uses=0] @o = constant i1 true ; <i1*> [#uses=0]
@p = constant i1 sdiv (i1 true, i1 true) ; <i1*> [#uses=0] @p = constant i1 true ; <i1*> [#uses=0]
@q = constant i1 true ; <i1*> [#uses=0] @q = constant i1 true ; <i1*> [#uses=0]
@r = 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] @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]