[llvm-commits] [llvm] r41983 - in /llvm/trunk: include/llvm/Instructions.h lib/Target/CBackend/CBackend.cpp
Chris Lattner
sabre at nondot.org
Fri Sep 14 23:51:04 PDT 2007
Author: lattner
Date: Sat Sep 15 01:51:03 2007
New Revision: 41983
URL: http://llvm.org/viewvc/llvm-project?rev=41983&view=rev
Log:
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.
Modified:
llvm/trunk/include/llvm/Instructions.h
llvm/trunk/lib/Target/CBackend/CBackend.cpp
Modified: llvm/trunk/include/llvm/Instructions.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Instructions.h?rev=41983&r1=41982&r2=41983&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Instructions.h (original)
+++ llvm/trunk/include/llvm/Instructions.h Sat Sep 15 01:51:03 2007
@@ -660,7 +660,7 @@
/// @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.
Modified: llvm/trunk/lib/Target/CBackend/CBackend.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/CBackend/CBackend.cpp?rev=41983&r1=41982&r2=41983&view=diff
==============================================================================
--- llvm/trunk/lib/Target/CBackend/CBackend.cpp (original)
+++ llvm/trunk/lib/Target/CBackend/CBackend.cpp Sat Sep 15 01:51:03 2007
@@ -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 << ")";
- 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 @@
// 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 << "))";
More information about the llvm-commits
mailing list