mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-08-17 21:29:20 +00:00
Move code out of indentation one level to make it easier to read.
Disable the xform for < > cases. It turns out that the following is being miscompiled: bool %test(sbyte %S) { %T = cast sbyte %S to uint %V = setgt uint %T, 255 ret bool %V } git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@19628 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
7ece380440
commit
b352fa5853
@ -2438,13 +2438,11 @@ Instruction *InstCombiner::visitSetCondInst(BinaryOperator &I) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
// (setcc (cast X to larger), CI)
|
// (setcc (cast X to larger), CI)
|
||||||
case Instruction::Cast: {
|
case Instruction::Cast:
|
||||||
Instruction* replacement =
|
if (Instruction *R =
|
||||||
visitSetCondInstWithCastAndConstant(I,cast<CastInst>(LHSI),CI);
|
visitSetCondInstWithCastAndConstant(I,cast<CastInst>(LHSI),CI))
|
||||||
if (replacement)
|
return R;
|
||||||
return replacement;
|
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
|
|
||||||
case Instruction::Shl: // (setcc (shl X, ShAmt), CI)
|
case Instruction::Shl: // (setcc (shl X, ShAmt), CI)
|
||||||
if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
|
if (ConstantUInt *ShAmt = dyn_cast<ConstantUInt>(LHSI->getOperand(1))) {
|
||||||
@ -2919,61 +2917,67 @@ InstCombiner::visitSetCondInstWithCastAndConstant(BinaryOperator&I,
|
|||||||
ConstantInt* CI) {
|
ConstantInt* CI) {
|
||||||
const Type *SrcTy = LHSI->getOperand(0)->getType();
|
const Type *SrcTy = LHSI->getOperand(0)->getType();
|
||||||
const Type *DestTy = LHSI->getType();
|
const Type *DestTy = LHSI->getType();
|
||||||
if (SrcTy->isIntegral() && DestTy->isIntegral()) {
|
if (!SrcTy->isIntegral() || !DestTy->isIntegral())
|
||||||
unsigned SrcBits = SrcTy->getPrimitiveSize()*8;
|
return 0;
|
||||||
unsigned DestBits = DestTy->getPrimitiveSize()*8;
|
|
||||||
if (SrcTy == Type::BoolTy)
|
unsigned SrcBits = SrcTy->getPrimitiveSize()*8;
|
||||||
SrcBits = 1;
|
unsigned DestBits = DestTy->getPrimitiveSize()*8;
|
||||||
if (DestTy == Type::BoolTy)
|
if (SrcTy == Type::BoolTy)
|
||||||
DestBits = 1;
|
SrcBits = 1;
|
||||||
if (SrcBits < DestBits) {
|
if (DestTy == Type::BoolTy)
|
||||||
// There are fewer bits in the source of the cast than in the result
|
DestBits = 1;
|
||||||
// of the cast. Any other case doesn't matter because the constant
|
if (SrcBits < DestBits) {
|
||||||
// value won't have changed due to sign extension.
|
// There are fewer bits in the source of the cast than in the result
|
||||||
Constant *NewCst = ConstantExpr::getCast(CI, SrcTy);
|
// of the cast. Any other case doesn't matter because the constant
|
||||||
if (ConstantExpr::getCast(NewCst, DestTy) == CI) {
|
// value won't have changed due to sign extension.
|
||||||
// The constant value operand of the setCC before and after a
|
Constant *NewCst = ConstantExpr::getCast(CI, SrcTy);
|
||||||
// cast to the source type of the cast instruction is the same
|
if (ConstantExpr::getCast(NewCst, DestTy) == CI) {
|
||||||
// value, so we just replace with the same setcc opcode, but
|
// The constant value operand of the setCC before and after a
|
||||||
// using the source value compared to the constant casted to the
|
// cast to the source type of the cast instruction is the same
|
||||||
// source type.
|
// value, so we just replace with the same setcc opcode, but
|
||||||
if (SrcTy->isSigned() && DestTy->isUnsigned()) {
|
// using the source value compared to the constant casted to the
|
||||||
CastInst* Cst = new CastInst(LHSI->getOperand(0),
|
// source type.
|
||||||
SrcTy->getUnsignedVersion(), LHSI->getName());
|
if (SrcTy->isSigned() && DestTy->isUnsigned()) {
|
||||||
InsertNewInstBefore(Cst,I);
|
CastInst* Cst = new CastInst(LHSI->getOperand(0),
|
||||||
return new SetCondInst(I.getOpcode(), Cst,
|
SrcTy->getUnsignedVersion(),
|
||||||
ConstantExpr::getCast(CI, SrcTy->getUnsignedVersion()));
|
LHSI->getName());
|
||||||
}
|
InsertNewInstBefore(Cst,I);
|
||||||
return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),NewCst);
|
return new SetCondInst(I.getOpcode(), Cst,
|
||||||
}
|
ConstantExpr::getCast(CI,
|
||||||
// The constant value before and after a cast to the source type
|
SrcTy->getUnsignedVersion()));
|
||||||
// is different, so various cases are possible depending on the
|
|
||||||
// opcode and the signs of the types involved in the cast.
|
|
||||||
switch (I.getOpcode()) {
|
|
||||||
case Instruction::SetLT: {
|
|
||||||
Constant* Max = ConstantIntegral::getMaxValue(SrcTy);
|
|
||||||
Max = ConstantExpr::getCast(Max, DestTy);
|
|
||||||
return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
|
|
||||||
}
|
|
||||||
case Instruction::SetGT: {
|
|
||||||
Constant* Min = ConstantIntegral::getMinValue(SrcTy);
|
|
||||||
Min = ConstantExpr::getCast(Min, DestTy);
|
|
||||||
return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
|
|
||||||
}
|
|
||||||
case Instruction::SetEQ:
|
|
||||||
// We're looking for equality, and we know the values are not
|
|
||||||
// equal so replace with constant False.
|
|
||||||
return ReplaceInstUsesWith(I, ConstantBool::False);
|
|
||||||
case Instruction::SetNE:
|
|
||||||
// We're testing for inequality, and we know the values are not
|
|
||||||
// equal so replace with constant True.
|
|
||||||
return ReplaceInstUsesWith(I, ConstantBool::True);
|
|
||||||
case Instruction::SetLE:
|
|
||||||
case Instruction::SetGE:
|
|
||||||
assert(!"SetLE and SetGE should be handled elsewhere");
|
|
||||||
default:
|
|
||||||
assert(!"unknown integer comparison");
|
|
||||||
}
|
}
|
||||||
|
return new SetCondInst(I.getOpcode(), LHSI->getOperand(0),NewCst);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The constant value before and after a cast to the source type
|
||||||
|
// is different, so various cases are possible depending on the
|
||||||
|
// opcode and the signs of the types involved in the cast.
|
||||||
|
switch (I.getOpcode()) {
|
||||||
|
case Instruction::SetLT: {
|
||||||
|
return 0;
|
||||||
|
Constant* Max = ConstantIntegral::getMaxValue(SrcTy);
|
||||||
|
Max = ConstantExpr::getCast(Max, DestTy);
|
||||||
|
return ReplaceInstUsesWith(I, ConstantExpr::getSetLT(Max, CI));
|
||||||
|
}
|
||||||
|
case Instruction::SetGT: {
|
||||||
|
return 0; // FIXME! RENABLE. This breaks for (cast sbyte to uint) > 255
|
||||||
|
Constant* Min = ConstantIntegral::getMinValue(SrcTy);
|
||||||
|
Min = ConstantExpr::getCast(Min, DestTy);
|
||||||
|
return ReplaceInstUsesWith(I, ConstantExpr::getSetGT(Min, CI));
|
||||||
|
}
|
||||||
|
case Instruction::SetEQ:
|
||||||
|
// We're looking for equality, and we know the values are not
|
||||||
|
// equal so replace with constant False.
|
||||||
|
return ReplaceInstUsesWith(I, ConstantBool::False);
|
||||||
|
case Instruction::SetNE:
|
||||||
|
// We're testing for inequality, and we know the values are not
|
||||||
|
// equal so replace with constant True.
|
||||||
|
return ReplaceInstUsesWith(I, ConstantBool::True);
|
||||||
|
case Instruction::SetLE:
|
||||||
|
case Instruction::SetGE:
|
||||||
|
assert(0 && "SetLE and SetGE should be handled elsewhere");
|
||||||
|
default:
|
||||||
|
assert(0 && "unknown integer comparison");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
|
Loading…
Reference in New Issue
Block a user