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:
Chris Lattner 2007-09-15 06:51:03 +00:00
parent b90795fd79
commit 5bda9e49ec
2 changed files with 28 additions and 46 deletions

View File

@ -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.

View File

@ -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 << "))";