mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-01-28 21:34:23 +00:00
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:
parent
61783d7322
commit
1c14c29746
@ -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.
|
||||||
|
@ -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]
|
||||||
|
Loading…
x
Reference in New Issue
Block a user