mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-13 22:24:07 +00:00
"ret (constexpr)" can't be folded into a Constant. Add a method to
Analysis/ConstantFolding to fold ConstantExpr's, then make instcombine use it to try to use targetdata to fold constant expressions on void instructions. Also extend the icmp(inttoptr, inttoptr) folding to handle the case where int size != ptr size. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51559 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -312,6 +312,25 @@ Constant *llvm::ConstantFoldInstruction(Instruction *I, const TargetData *TD) {
|
||||
&Ops[0], Ops.size(), TD);
|
||||
}
|
||||
|
||||
/// ConstantFoldConstantExpression - Attempt to fold the constant expression
|
||||
/// using the specified TargetData. If successful, the constant result is
|
||||
/// result is returned, if not, null is returned.
|
||||
Constant *llvm::ConstantFoldConstantExpression(ConstantExpr *CE,
|
||||
const TargetData *TD) {
|
||||
assert(TD && "ConstantFoldConstantExpression requires a valid TargetData.");
|
||||
|
||||
SmallVector<Constant*, 8> Ops;
|
||||
for (User::op_iterator i = CE->op_begin(), e = CE->op_end(); i != e; ++i)
|
||||
Ops.push_back(cast<Constant>(*i));
|
||||
|
||||
if (CE->isCompare())
|
||||
return ConstantFoldCompareInstOperands(CE->getPredicate(),
|
||||
&Ops[0], Ops.size(), TD);
|
||||
else
|
||||
return ConstantFoldInstOperands(CE->getOpcode(), CE->getType(),
|
||||
&Ops[0], Ops.size(), TD);
|
||||
}
|
||||
|
||||
/// ConstantFoldInstOperands - Attempt to constant fold an instruction with the
|
||||
/// specified opcode and operands. If successful, the constant result is
|
||||
/// returned, if not, null is returned. Note that this function can fail when
|
||||
@ -398,7 +417,7 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
|
||||
const TargetData *TD) {
|
||||
// fold: icmp (inttoptr x), null -> icmp x, 0
|
||||
// fold: icmp (ptrtoint x), 0 -> icmp x, null
|
||||
// fold: icmp (inttoptr x), (inttoptr y) -> icmp x, y
|
||||
// fold: icmp (inttoptr x), (inttoptr y) -> icmp trunc/zext x, trunc/zext y
|
||||
// fold: icmp (ptrtoint x), (ptrtoint y) -> icmp x, y
|
||||
//
|
||||
// ConstantExpr::getCompare cannot do this, because it doesn't have TD
|
||||
@ -426,21 +445,31 @@ Constant *llvm::ConstantFoldCompareInstOperands(unsigned Predicate,
|
||||
}
|
||||
}
|
||||
|
||||
if (TD && isa<ConstantExpr>(Ops[1]) &&
|
||||
cast<ConstantExpr>(Ops[1])->getOpcode() == CE0->getOpcode()) {
|
||||
const Type *IntPtrTy = TD->getIntPtrType();
|
||||
// Only do this transformation if the int is intptrty in size, otherwise
|
||||
// there is a truncation or extension that we aren't modeling.
|
||||
if ((CE0->getOpcode() == Instruction::IntToPtr &&
|
||||
CE0->getOperand(0)->getType() == IntPtrTy &&
|
||||
Ops[1]->getOperand(0)->getType() == IntPtrTy) ||
|
||||
(CE0->getOpcode() == Instruction::PtrToInt &&
|
||||
CE0->getType() == IntPtrTy &&
|
||||
CE0->getOperand(0)->getType() == Ops[1]->getOperand(0)->getType())) {
|
||||
Constant *NewOps[] = {
|
||||
CE0->getOperand(0), cast<ConstantExpr>(Ops[1])->getOperand(0)
|
||||
};
|
||||
return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
|
||||
if (ConstantExpr *CE1 = dyn_cast<ConstantExpr>(Ops[1])) {
|
||||
if (TD && CE0->getOpcode() == CE1->getOpcode()) {
|
||||
const Type *IntPtrTy = TD->getIntPtrType();
|
||||
|
||||
if (CE0->getOpcode() == Instruction::IntToPtr) {
|
||||
// Convert the integer value to the right size to ensure we get the
|
||||
// proper extension or truncation.
|
||||
Constant *C0 = ConstantExpr::getIntegerCast(CE0->getOperand(0),
|
||||
IntPtrTy, false);
|
||||
Constant *C1 = ConstantExpr::getIntegerCast(CE1->getOperand(0),
|
||||
IntPtrTy, false);
|
||||
Constant *NewOps[] = { C0, C1 };
|
||||
return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
|
||||
}
|
||||
|
||||
// Only do this transformation if the int is intptrty in size, otherwise
|
||||
// there is a truncation or extension that we aren't modeling.
|
||||
if ((CE0->getOpcode() == Instruction::PtrToInt &&
|
||||
CE0->getType() == IntPtrTy &&
|
||||
CE0->getOperand(0)->getType() == CE1->getOperand(0)->getType())) {
|
||||
Constant *NewOps[] = {
|
||||
CE0->getOperand(0), CE1->getOperand(0)
|
||||
};
|
||||
return ConstantFoldCompareInstOperands(Predicate, NewOps, 2, TD);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user