From 5bda9e49ec9432b610289aae4ee251c803513851 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 15 Sep 2007 06:51:03 +0000 Subject: [PATCH] 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 --- include/llvm/Instructions.h | 2 +- lib/Target/CBackend/CBackend.cpp | 72 ++++++++++++-------------------- 2 files changed, 28 insertions(+), 46 deletions(-) diff --git a/include/llvm/Instructions.h b/include/llvm/Instructions.h index 5aeccec8f46..98df15e4e94 100644 --- a/include/llvm/Instructions.h +++ b/include/llvm/Instructions.h @@ -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. diff --git a/lib/Target/CBackend/CBackend.cpp b/lib/Target/CBackend/CBackend.cpp index 5f6d5905bf5..ea071155cee 100644 --- a/lib/Target/CBackend/CBackend.cpp +++ b/lib/Target/CBackend/CBackend.cpp @@ -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(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 << "))"; -- 2.34.1