[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