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
diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp
index 5f6d590..ea07115 100644
--- a/lib/Target/CBackend/CBackend.cpp
+++ b/lib/Target/CBackend/CBackend.cpp
@@ -138,7 +138,7 @@
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 @@
// 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 << ")";
+ if (!shouldCast) {
writeOperand(Operand);
- Out << ")";
- } else
- 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 @@
// 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 @@
default: cerr << "Invalid icmp predicate!" << I; abort();
}
- writeOperandWithCast(I.getOperand(1), I.getPredicate());
+ writeOperandWithCast(I.getOperand(1), I);
if (NeedsClosingParens)
Out << "))";