mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-02-21 21:29:41 +00:00
Fix PR1666, SPASS with the CBE and 254.gap with the CBE.
GCC optimizes away things like ptr < NULL to false. To "fix" this, have the CBE emit casts of pointers to intptr_t when doing relational pointer comparisons. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@41983 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
b90795fd79
commit
5bda9e49ec
@ -660,7 +660,7 @@ public:
|
||||
|
||||
/// @returns true if the predicate of this ICmpInst is signed, false otherwise
|
||||
/// @brief Determine if this instruction's predicate is signed.
|
||||
bool isSignedPredicate() { return isSignedPredicate(getPredicate()); }
|
||||
bool isSignedPredicate() const { return isSignedPredicate(getPredicate()); }
|
||||
|
||||
/// @returns true if the predicate provided is signed, false otherwise
|
||||
/// @brief Determine if the predicate is signed.
|
||||
|
@ -138,7 +138,7 @@ namespace {
|
||||
void writeOperandRaw(Value *Operand);
|
||||
void writeOperandInternal(Value *Operand);
|
||||
void writeOperandWithCast(Value* Operand, unsigned Opcode);
|
||||
void writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate);
|
||||
void writeOperandWithCast(Value* Operand, const ICmpInst &I);
|
||||
bool writeInstructionCast(const Instruction &I);
|
||||
|
||||
private :
|
||||
@ -1248,52 +1248,34 @@ void CWriter::writeOperandWithCast(Value* Operand, unsigned Opcode) {
|
||||
|
||||
// Write the operand with a cast to another type based on the icmp predicate
|
||||
// being used.
|
||||
void CWriter::writeOperandWithCast(Value* Operand, ICmpInst::Predicate predicate) {
|
||||
|
||||
// Extract the operand's type, we'll need it.
|
||||
const Type* OpTy = Operand->getType();
|
||||
|
||||
// Indicate whether to do the cast or not.
|
||||
bool shouldCast = false;
|
||||
|
||||
// Indicate whether the cast should be to a signed type or not.
|
||||
bool castIsSigned = false;
|
||||
|
||||
// Based on the Opcode for which this Operand is being written, determine
|
||||
// the new type to which the operand should be casted by setting the value
|
||||
// of OpTy. If we change OpTy, also set shouldCast to true.
|
||||
switch (predicate) {
|
||||
default:
|
||||
// for eq and ne, it doesn't matter
|
||||
break;
|
||||
case ICmpInst::ICMP_UGT:
|
||||
case ICmpInst::ICMP_UGE:
|
||||
case ICmpInst::ICMP_ULT:
|
||||
case ICmpInst::ICMP_ULE:
|
||||
shouldCast = true;
|
||||
break;
|
||||
case ICmpInst::ICMP_SGT:
|
||||
case ICmpInst::ICMP_SGE:
|
||||
case ICmpInst::ICMP_SLT:
|
||||
case ICmpInst::ICMP_SLE:
|
||||
shouldCast = true;
|
||||
castIsSigned = true;
|
||||
break;
|
||||
}
|
||||
void CWriter::writeOperandWithCast(Value* Operand, const ICmpInst &Cmp) {
|
||||
// This has to do a cast to ensure the operand has the right signedness.
|
||||
// Also, if the operand is a pointer, we make sure to cast to an integer when
|
||||
// doing the comparison both for signedness and so that the C compiler doesn't
|
||||
// optimize things like "p < NULL" to false (p may contain an integer value
|
||||
// f.e.).
|
||||
bool shouldCast = Cmp.isRelational();
|
||||
|
||||
// Write out the casted operand if we should, otherwise just write the
|
||||
// operand.
|
||||
if (shouldCast) {
|
||||
Out << "((";
|
||||
if (OpTy->isInteger() && OpTy != Type::Int1Ty)
|
||||
printSimpleType(Out, OpTy, castIsSigned);
|
||||
else
|
||||
printType(Out, OpTy); // not integer, sign doesn't matter
|
||||
Out << ")";
|
||||
writeOperand(Operand);
|
||||
Out << ")";
|
||||
} else
|
||||
if (!shouldCast) {
|
||||
writeOperand(Operand);
|
||||
return;
|
||||
}
|
||||
|
||||
// Should this be a signed comparison? If so, convert to signed.
|
||||
bool castIsSigned = Cmp.isSignedPredicate();
|
||||
|
||||
// If the operand was a pointer, convert to a large integer type.
|
||||
const Type* OpTy = Operand->getType();
|
||||
if (isa<PointerType>(OpTy))
|
||||
OpTy = TD->getIntPtrType();
|
||||
|
||||
Out << "((";
|
||||
printSimpleType(Out, OpTy, castIsSigned);
|
||||
Out << ")";
|
||||
writeOperand(Operand);
|
||||
Out << ")";
|
||||
}
|
||||
|
||||
// generateCompilerSpecificCode - This is where we add conditional compilation
|
||||
@ -2265,7 +2247,7 @@ void CWriter::visitICmpInst(ICmpInst &I) {
|
||||
// Certain icmp predicate require the operand to be forced to a specific type
|
||||
// so we use writeOperandWithCast here instead of writeOperand. Similarly
|
||||
// below for operand 1
|
||||
writeOperandWithCast(I.getOperand(0), I.getPredicate());
|
||||
writeOperandWithCast(I.getOperand(0), I);
|
||||
|
||||
switch (I.getPredicate()) {
|
||||
case ICmpInst::ICMP_EQ: Out << " == "; break;
|
||||
@ -2281,7 +2263,7 @@ void CWriter::visitICmpInst(ICmpInst &I) {
|
||||
default: cerr << "Invalid icmp predicate!" << I; abort();
|
||||
}
|
||||
|
||||
writeOperandWithCast(I.getOperand(1), I.getPredicate());
|
||||
writeOperandWithCast(I.getOperand(1), I);
|
||||
if (NeedsClosingParens)
|
||||
Out << "))";
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user