[llvm-commits] SETCC Patches: #3

Chris Lattner clattner at apple.com
Mon Dec 11 22:51:38 PST 2006


On Dec 10, 2006, at 3:43 PM, Reid Spencer wrote:

> All,
>
> Here's the SETCC patch to convert SetCondInst (SetCC) instructions  
> into
> ICmpInst. Here's somethings you should know about this patch:


This is all the rest, except for instcombine.




Index: tools/llvm-upgrade/UpgradeParser.y
===================================================================
RCS file: /var/cvs/llvm/llvm/tools/llvm-upgrade/UpgradeParser.y,v
retrieving revision 1.24
diff -t -d -u -p -5 -r1.24 UpgradeParser.y
--- tools/llvm-upgrade/UpgradeParser.y	9 Dec 2006 19:40:41 -0000	1.24
+++ tools/llvm-upgrade/UpgradeParser.y	10 Dec 2006 23:27:00 -0000
@@ -21,11 +21,11 @@
  #include <cassert>

  #define YYERROR_VERBOSE 1
  #define YYINCLUDED_STDLIB_H
  #define YYDEBUG 1
-#define UPGRADE_SETCOND_OPS 0
+#define UPGRADE_SETCOND_OPS 1
  #define GENERATE_FCMP_INSTS 0

  int yylex();                       // declaration" of xxx warnings.
  int yyparse();
  extern int yydebug;

This #ifdef should go away now, since it's always on.


Index: lib/ExecutionEngine/Interpreter/Execution.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/ExecutionEngine/Interpreter/ 
Execution.cpp,v
retrieving revision 1.152
diff -t -d -u -p -5 -r1.152 Execution.cpp
--- lib/ExecutionEngine/Interpreter/Execution.cpp	7 Dec 2006 01:30:31  
-0000	1.152
+++ lib/ExecutionEngine/Interpreter/Execution.cpp	10 Dec 2006  
23:26:54 -0000
...

+static GenericValue executeICMP_ULT(GenericValue Src1, GenericValue  
Src2,
+                                    const Type *Ty) {
+  GenericValue Dest;
+  switch (Ty->getTypeID()) {
+    IMPLEMENT_CMP(<, UByte);
+    IMPLEMENT_CMP(<, UShort);
+    IMPLEMENT_CMP(<, UInt);
+    IMPLEMENT_CMP(<, ULong);
+    IMPLEMENT_POINTERCMP(<);
+  default:
+    cerr << "Unhandled type for ICMP_ULT predicate: " << *Ty << "\n";
+    abort();
+  }
+  return Dest;
+}

The interpreter is broken: all unsigned comparisons with signed  
operands will hit the unhandled type case.


Index: lib/Target/CBackend/Writer.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Target/CBackend/Writer.cpp,v
retrieving revision 1.294
diff -t -d -u -p -5 -r1.294 Writer.cpp
--- lib/Target/CBackend/Writer.cpp	7 Dec 2006 23:41:45 -0000	1.294
+++ lib/Target/CBackend/Writer.cpp	10 Dec 2006 23:26:54 -0000
@@ -712,10 +717,44 @@ void CWriter::printConstant(Constant *CP
        case Instruction::SetGT: Out << " > "; break;
        case Instruction::SetGE: Out << " >= "; break;
        case Instruction::Shl: Out << " << "; break;
        case Instruction::LShr:
        case Instruction::AShr: Out << " >> "; break;
+      case Instruction::ICmp:
+        switch (CE->getPredicate()) {
+          case ICmpInst::ICMP_EQ: Out << " == "; break;
+          case ICmpInst::ICMP_NE: Out << " != "; break;
+          case ICmpInst::ICMP_SLT:
+          case ICmpInst::ICMP_ULT: Out << " < "; break;
+          case ICmpInst::ICMP_SLE:
+          case ICmpInst::ICMP_ULE: Out << " <= "; break;
...

This apparently doesn't cast the operands of icmp constant exprs to  
the right sign.



@@ -1122,10 +1161,65 @@ void CWriter::writeOperandWithCast(Value
+
+// generateCompilerSpecificCode - This is where we add conditional  
compilation
+// directives to cater to specific compilers as need be.
+//
+
  // generateCompilerSpecificCode - This is where we add conditional  
compilation
  // directives to cater to specific compilers as need be.
  //

... There ya go again, trying to inflate your LOC count.


@@ -1982,10 +2076,49 @@ void CWriter::visitBinaryOperator(Instru
    if (needsCast) {
      Out << "))";
    }
  }

+void CWriter::visitICmpInst(Instruction &I) {
+  // icmp instruction.
+  assert(isa<ICmpInst>(I));
+

Drop the isa and later casts, change the argument to visitICmpInst to  
ICmpInst.


Index: lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/CodeGen/SelectionDAG/ 
SelectionDAGISel.cpp,v
retrieving revision 1.326
diff -t -d -u -p -5 -r1.326 SelectionDAGISel.cpp
--- lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	9 Dec 2006 02:42:38  
-0000	1.326
+++ lib/CodeGen/SelectionDAG/SelectionDAGISel.cpp	10 Dec 2006  
23:26:53 -0000

+      BOp = cast<Instruction>(Cond);
+      ISD::CondCode Condition;
+      if (SetCondInst *SCI = dyn_cast<SetCondInst>(Cond)) {
+        ISD::CondCode SignCond, UnsCond, FPCond;
+        switch (BOp->getOpcode()) {
+        default: assert(0 && "Unknown setcc opcode!");
+        case Instruction::SetEQ:
+          SignCond = ISD::SETEQ;
+          UnsCond  = ISD::SETEQ;
+          FPCond   = ISD::SETOEQ;
+          break;
+        case Instruction::SetNE:
+          SignCond = ISD::SETNE;
+          UnsCond  = ISD::SETNE;
+          FPCond   = ISD::SETUNE;
+          break;
+        case Instruction::SetLE:
+          SignCond = ISD::SETLE;
+          UnsCond  = ISD::SETULE;
+          FPCond   = ISD::SETOLE;
+          break;
+        case Instruction::SetGE:
+          SignCond = ISD::SETGE;
+          UnsCond  = ISD::SETUGE;
+          FPCond   = ISD::SETOGE;
+          break;
+        case Instruction::SetLT:
+          SignCond = ISD::SETLT;
+          UnsCond  = ISD::SETULT;
+          FPCond   = ISD::SETOLT;
+          break;
+        case Instruction::SetGT:
+          SignCond = ISD::SETGT;
+          UnsCond  = ISD::SETUGT;
+          FPCond   = ISD::SETOGT;
+          break;
+        }
+        const Type *OpType = SCI->getOperand(0)->getType();
+        if (const PackedType *PTy = dyn_cast<PackedType>(OpType))
+          OpType = PTy->getElementType();
+
+        if (!FiniteOnlyFPMath() && OpType->isFloatingPoint())
+          Condition = FPCond;
+        else if (OpType->isUnsigned())
+          Condition = UnsCond;
+        else
+          Condition = SignCond;

You can drop UnsCond here, as SetCondInst doesn't apply to integers  
anymore.


+      } else if (FCmpInst *FC = dyn_cast<FCmpInst>(Cond)) {
+        switch (FC->getPredicate()) {
+        default: assert(0 && "Unknown fcmp predicate opcode!");
+        case FCmpInst::FCMP_FALSE: Condition = ISD::SETFALSE; break;
+        case FCmpInst::FCMP_OEQ:   Condition = ISD::SETOEQ; break;
+        case FCmpInst::FCMP_OGT:   Condition = ISD::SETOGT; break;
+        case FCmpInst::FCMP_OGE:   Condition = ISD::SETOGE; break;
+        case FCmpInst::FCMP_OLT:   Condition = ISD::SETOLT; break;
+        case FCmpInst::FCMP_OLE:   Condition = ISD::SETOLE; break;
+        case FCmpInst::FCMP_ONE:   Condition = ISD::SETONE; break;
+        case FCmpInst::FCMP_ORD:   Condition = ISD::SETO;   break;
+        case FCmpInst::FCMP_UNO:   Condition = ISD::SETUO;  break;
+        case FCmpInst::FCMP_UEQ:   Condition = ISD::SETUEQ; break;
+        case FCmpInst::FCMP_UGT:   Condition = ISD::SETUGT; break;
+        case FCmpInst::FCMP_UGE:   Condition = ISD::SETUGE; break;
+        case FCmpInst::FCMP_ULT:   Condition = ISD::SETULT; break;
+        case FCmpInst::FCMP_ULE:   Condition = ISD::SETULE; break;
+        case FCmpInst::FCMP_UNE:   Condition = ISD::SETUNE; break;
+        case FCmpInst::FCMP_TRUE:  Condition = ISD::SETTRUE; break;
+        }

This (when it becomes active) isn't sufficient.  When  
FiniteOnlyFPMath is enabled, all the 'o's and 'u's should get dropped.

  void SelectionDAGLowering::visitFCmp(User &I) {
+  FCmpInst::Predicate predicate = FCmpInst::BAD_FCMP_PREDICATE;
+  if (FCmpInst *FC = dyn_cast<FCmpInst>(&I))

likewise.

diff -t -d -u -p -5 -r1.107 SimplifyCFG.cpp
--- lib/Transforms/Utils/SimplifyCFG.cpp	27 Nov 2006 01:05:10 -0000	 
1.107
+++ lib/Transforms/Utils/SimplifyCFG.cpp	10 Dec 2006 23:26:51 -0000
@@ -388,23 +390,43 @@ static bool DominatesMergePoint(Value *V
      }

    return true;
  }

-// GatherConstantSetEQs - Given a potentially 'or'd together  
collection of seteq
-// instructions that compare a value against a constant, return the  
value being
-// compared, and stick the constant into the Values vector.
+// GatherConstantSetEQs - Given a potentially 'or'd together  
collection of
+// icmp_eq instructions that compare a value against a constant,  
return the
+// value being compared, and stick the constant into the Values vector.
  static Value *GatherConstantSetEQs(Value *V,  
std::vector<ConstantInt*> &Values){
    if (Instruction *Inst = dyn_cast<Instruction>(V))
      if (Inst->getOpcode() == Instruction::SetEQ) {
        if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand 
(1))) {
          Values.push_back(C);
          return Inst->getOperand(0);
        } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))) {
          Values.push_back(C);
          return Inst->getOperand(1);
        }

This code is dead because integer seteq can't exist anymore (it's icmp).

+    } else if (Inst->getOpcode() == Instruction::ICmp &&
+        cast<ICmpInst>(Inst)->getPredicate() == ICmpInst::ICMP_EQ) {
+      if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand 
(1))) {
+        Values.push_back(C);
+        return Inst->getOperand(0);
+      } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))) {
+        Values.push_back(C);
+        return Inst->getOperand(1);
+      }
+    } else if (FCmpInst *FCI = dyn_cast<FCmpInst>(Inst)) {
+      FCmpInst::Predicate pred = FCI->getPredicate();
+      if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+        if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand 
(1))) {
+          Values.push_back(C);
+          return Inst->getOperand(0);
+        } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))){
+          Values.push_back(C);
+          return Inst->getOperand(1);
+        }
+      }

FCmpInst's can't have constantint operands, this code is dead.

@@ -423,10 +445,30 @@ static Value *GatherConstantSetNEs(Value
          return Inst->getOperand(0);
        } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))) {
          Values.push_back(C);
          return Inst->getOperand(1);
        }
+    } else if (Inst->getOpcode() == Instruction::ICmp &&
+               cast<ICmpInst>(Inst)->getPredicate() ==  
ICmpInst::ICMP_NE) {
+      if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand 
(1))) {
+        Values.push_back(C);
+        return Inst->getOperand(0);
+      } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))) {
+        Values.push_back(C);
+        return Inst->getOperand(1);
+      }
+    } else if (FCmpInst *FCI = dyn_cast<FCmpInst>(Inst)) {
+      FCmpInst::Predicate pred = FCI->getPredicate();
+      if (pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+        if (ConstantInt *C = dyn_cast<ConstantInt>(Inst->getOperand 
(1))) {
+          Values.push_back(C);
+          return Inst->getOperand(0);
+        } else if (ConstantInt *C = dyn_cast<ConstantInt>(Inst- 
 >getOperand(0))){
+          Values.push_back(C);
+          return Inst->getOperand(1);
+        }
+      }


Likewise.  Since you're handling integers, you can nuke the old  
SetCondInst code here.




@@ -845,12 +887,11 @@ static bool HoistThenElseCodeToIf(Branch
    // identical order.
    BasicBlock *BB1 = BI->getSuccessor(0);  // The true destination.
    BasicBlock *BB2 = BI->getSuccessor(1);  // The false destination

    Instruction *I1 = BB1->begin(), *I2 = BB2->begin();
-  if (I1->getOpcode() != I2->getOpcode() || !I1->isIdenticalTo(I2) ||
-      isa<PHINode>(I1) || isa<InvokeInst>(I1))
+  if (!I1->isIdenticalTo(I2) || isa<PHINode>(I1) || isa<InvokeInst> 
(I1))
      return false;

    // If we get here, we can hoist at least one instruction.
    BasicBlock *BIParent = BI->getParent();


Why did you drop the opcode check?  It is a fast reject path.




@@ -868,11 +909,11 @@ static bool HoistThenElseCodeToIf(Branch
        I2->replaceAllUsesWith(I1);
      BB2->getInstList().erase(I2);

      I1 = BB1->begin();
      I2 = BB2->begin();
-  } while (I1->getOpcode() == I2->getOpcode() && I1->isIdenticalTo 
(I2));
+  } while (I1->isIdenticalTo(I2));


likewise.


Index: lib/Transforms/Utils/CloneFunction.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/Utils/CloneFunction.cpp,v
retrieving revision 1.33
diff -t -d -u -p -5 -r1.33 CloneFunction.cpp
--- lib/Transforms/Utils/CloneFunction.cpp	5 Nov 2006 19:31:28 -0000	 
1.33
+++ lib/Transforms/Utils/CloneFunction.cpp	10 Dec 2006 23:26:50 -0000
@@ -276,16 +276,19 @@ void PruningFunctionCloner::CloneBlock(c

  /// ConstantFoldMappedInstruction - Constant fold the specified  
instruction,
  /// mapping its operands through ValueMap if they are available.
  Constant *PruningFunctionCloner::
  ConstantFoldMappedInstruction(const Instruction *I) {
-  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I)) {
+  if (isa<BinaryOperator>(I) || isa<ShiftInst>(I) || isa<CmpInst>(I)) {
      if (Constant *Op0 = dyn_cast_or_null<Constant>(MapValue(I- 
 >getOperand(0),
                                                               
ValueMap)))
        if (Constant *Op1 = dyn_cast_or_null<Constant>(MapValue(I- 
 >getOperand(1),
                                                                 
ValueMap)))
-        return ConstantExpr::get(I->getOpcode(), Op0, Op1);
+        return isa<CmpInst>(I) ?
+               ConstantExpr::getCompare(I->getOpcode(),
+                 cast<CmpInst>(I)->getPredicate(), Op0, Op1) :
+               ConstantExpr::get(I->getOpcode(), Op0, Op1);
      return 0;
    }

It seems more natural to split CmpInst out from binop/shift handling  
into a separate if, to eliminate the ternary operator.


===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/Scalar/Reassociate.cpp,v
retrieving revision 1.68
diff -t -d -u -p -5 -r1.68 Reassociate.cpp
--- lib/Transforms/Scalar/Reassociate.cpp	7 Dec 2006 20:04:42 -0000	1.68
+++ lib/Transforms/Scalar/Reassociate.cpp	10 Dec 2006 23:26:49 -0000
@@ -754,12 +755,12 @@ void Reassociate::ReassociateBB(BasicBlo
          MadeChange = true;
          BI = NI;
        }

      // Reject cases where it is pointless to do this.
-    if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
-        isa<PackedType>(BI->getType()))
+    if (!isa<BinaryOperator>(BI) || BI->getType()->isFloatingPoint() ||
+         isa<PackedType>(BI->getType()))
        continue;  // Floating point ops are not associative.


This change looks like an incorrect indentation change.



Index: lib/Transforms/Scalar/LoopUnswitch.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/Scalar/LoopUnswitch.cpp,v
retrieving revision 1.51
diff -t -d -u -p -5 -r1.51 LoopUnswitch.cpp
--- lib/Transforms/Scalar/LoopUnswitch.cpp	6 Dec 2006 17:46:33 -0000	 
1.51
+++ lib/Transforms/Scalar/LoopUnswitch.cpp	10 Dec 2006 23:26:48 -0000
@@ -486,11 +486,14 @@ static void EmitPreheaderBranchOnConditi
                                             Instruction *InsertPt) {
    // Insert a conditional branch on LIC to the two preheaders.  The  
original
    // code is the true version and the new code is the false version.
    Value *BranchVal = LIC;
    if (!isa<ConstantBool>(Val)) {
-    BranchVal = BinaryOperator::createSetEQ(LIC, Val, "tmp", InsertPt);
+    if (Val->getType()->isFloatingPoint())
+      BranchVal = BinaryOperator::createSetEQ(LIC, Val, "tmp",  
InsertPt);
+    else
+      BranchVal = new ICmpInst(ICmpInst::ICMP_EQ, LIC, Val, "tmp",  
InsertPt);
    } else if (Val != ConstantBool::getTrue()) {
      // We want to enter the new loop when the condition is true.
      std::swap(TrueDest, FalseDest);
    }

It's not obvious from immediate context, but this is always an  
integer comparison.


diff -t -d -u -p -5 -r1.98 LoopStrengthReduce.cpp
--- lib/Transforms/Scalar/LoopStrengthReduce.cpp	7 Dec 2006 01:30:31  
-0000	1.98
+++ lib/Transforms/Scalar/LoopStrengthReduce.cpp	10 Dec 2006 23:26:48  
-0000
@@ -1187,14 +1187,20 @@ void LoopStrengthReduce::OptimizeIndvars
    PHINode *SomePHI = cast<PHINode>(L->getHeader()->begin());
    BasicBlock  *Preheader = L->getLoopPreheader();
    BasicBlock *LatchBlock =
     SomePHI->getIncomingBlock(SomePHI->getIncomingBlock(0) ==  
Preheader);
    BranchInst *TermBr = dyn_cast<BranchInst>(LatchBlock- 
 >getTerminator());
+  bool isICmp;
    if (!TermBr || TermBr->isUnconditional() ||
-      !isa<SetCondInst>(TermBr->getCondition()))
+      (!(isICmp = isa<ICmpInst>(TermBr->getCondition()) &&
+       !isa<SetCondInst>(TermBr->getCondition()))))
      return;
-  SetCondInst *Cond = cast<SetCondInst>(TermBr->getCondition());
+  Instruction *Cond;
+  if (isICmp)
+    Cond = cast<ICmpInst>(TermBr->getCondition());
+  else
+    Cond = cast<SetCondInst>(TermBr->getCondition());


This code only cares about integer comparisons.  Please change Cond  
to be ICmpInst*.



@@ -1223,11 +1229,14 @@ void LoopStrengthReduce::OptimizeIndvars
    if (&*++BasicBlock::iterator(Cond) != (Instruction*)TermBr) {
      if (Cond->hasOneUse()) {   // Condition has a single use, just  
move it.
        Cond->moveBefore(TermBr);
      } else {
        // Otherwise, clone the terminating condition and insert into  
the loopend.
-      Cond = cast<SetCondInst>(Cond->clone());
+      if (isICmp)
+        Cond = cast<ICmpInst>(Cond->clone());
+      else
+        Cond = cast<SetCondInst>(Cond->clone());
        Cond->setName(L->getHeader()->getName() + ".termcond");
        LatchBlock->getInstList().insert(TermBr, Cond);

        // Clone the IVUse, as the old use still exists!
        IVUsesByStride[*CondStride].addUser(CondUse->Offset, Cond,

Likewise.

@@ -1344,19 +1353,26 @@ void LoopStrengthReduce::runOnLoop(Loop
        // If all four cases above are true, then we can remove both  
the add and
        // the cann indvar.
        // FIXME: this needs to eliminate an induction variable even  
if it's being
        // compared against some value to decide loop termination.
        if (PN->hasOneUse()) {
-        BinaryOperator *BO = dyn_cast<BinaryOperator>(*(PN->use_begin 
()));
-        if (BO && BO->hasOneUse()) {
-          if (PN == *(BO->use_begin())) {
+        if (BinaryOperator *BO = dyn_cast<BinaryOperator>(*(PN- 
 >use_begin()))) {
+          if (BO->hasOneUse() && PN == *(BO->use_begin())) {
              DeadInsts.insert(BO);
              // Break the cycle, then delete the PHI.
              PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
              SE->deleteInstructionFromRecords(PN);
              PN->eraseFromParent();
            }
+        } else if (CmpInst *CI = dyn_cast<CmpInst>(*(PN->use_begin 
()))) {
+          if (CI->hasOneUse() && PN == *(CI->use_begin())) {
+            DeadInsts.insert(CI);
+            // Break the cycle, then delete the PHI.
+            PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
+            SE->deleteInstructionFromRecords(PN);
+            PN->eraseFromParent();
+          }

Instead of cloning the code, how about something like:

        // FIXME: this needs to eliminate an induction variable even  
if it's being
        // compared against some value to decide loop termination.
        if (PN->hasOneUse()) {
                  Instruction *BO = *PN->use_begin();
          if (isa<BinaryOperator>(BO) || isa<CmpInst>(BO)) {
+          if (BO->hasOneUse() && PN == *(BO->use_begin())) {
              DeadInsts.insert(BO);
              // Break the cycle, then delete the PHI.
              PN->replaceAllUsesWith(UndefValue::get(PN->getType()));
              SE->deleteInstructionFromRecords(PN);
              PN->eraseFromParent();
            }


===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/IPO/SimplifyLibCalls.cpp,v
retrieving revision 1.74
diff -t -d -u -p -5 -r1.74 SimplifyLibCalls.cpp
--- lib/Transforms/IPO/SimplifyLibCalls.cpp	6 Dec 2006 17:46:32 -0000	 
1.74
+++ lib/Transforms/IPO/SimplifyLibCalls.cpp	10 Dec 2006 23:26:42 -0000
@@ -941,10 +941,16 @@ static bool IsOnlyUsedInEqualsZeroCompar
      if (User->getOpcode() == Instruction::SetNE ||
          User->getOpcode() == Instruction::SetEQ) {
        if (isa<Constant>(User->getOperand(1)) &&
            cast<Constant>(User->getOperand(1))->isNullValue())
          continue;
+    } else if (ICmpInst *IC = dyn_cast<ICmpInst>(User)) {
+      if ((IC->getPredicate() == ICmpInst::ICMP_NE ||
+           IC->getPredicate() == ICmpInst::ICMP_EQ) &&
+          isa<Constant>(IC->getOperand(1)) &&
+          cast<Constant>(IC->getOperand(1))->isNullValue())
+        continue;
      } else if (CastInst *CI = dyn_cast<CastInst>(User))
        if (CI->getType() == Type::BoolTy)
          continue;
      // Unknown instruction.
      return false;

The FP case is dead here.

@@ -1769,13 +1775,13 @@ public:
      // isascii(c)   -> (unsigned)c < 128
      Value *V = CI->getOperand(1);
      if (V->getType()->isSigned())
        V = CastInst::createInferredCast(V, V->getType()- 
 >getUnsignedVersion(),
                                         V->getName(), CI);
-    Value *Cmp = BinaryOperator::createSetLT(V, ConstantInt::get(V- 
 >getType(),
-                                                                  128),
-                                             V->getName() 
+".isascii", CI);
+    Value *Cmp = new ICmpInst(ICmpInst::ICMP_ULT, V,
+                              ConstantInt::get(V->getType(), 128),
+                              V->getName()+".isascii", CI);
      if (Cmp->getType() != CI->getType())
        Cmp = CastInst::createInferredCast(
            Cmp, CI->getType(), Cmp->getName(), CI);
      CI->replaceAllUsesWith(Cmp);
      CI->eraseFromParent();



You can drop the createInferredCast (which should have been a  
bitcast) now that compares are signless?

diff -t -d -u -p -5 -r1.78 GlobalOpt.cpp
--- lib/Transforms/IPO/GlobalOpt.cpp	7 Dec 2006 01:30:31 -0000	1.78
+++ lib/Transforms/IPO/GlobalOpt.cpp	10 Dec 2006 23:26:41 -0000
@@ -722,15 +722,53 @@ static GlobalVariable *OptimizeGlobalAdd
    std::vector<StoreInst*> Stores;
    while (!GV->use_empty())
      if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
        while (!LI->use_empty()) {
          Use &LoadUse = LI->use_begin().getUse();
-        if (!isa<SetCondInst>(LoadUse.getUser()))
-          LoadUse = RepValue;
-        else {
+        if (CmpInst *CI = dyn_cast<CmpInst>(LoadUse.getUser())) {
+          // Replace the cmp X, 0 with a use of the bool value.
+          Value *LV = new LoadInst(InitBool, InitBool->getName() 
+".val", CI);
+          InitBoolUsed = true;
+          switch (CI->getPredicate()) {
+          default: assert(0 && "Unknown ICmp Predicate!");
+          case FCmpInst::FCMP_OLT:
+          case FCmpInst::FCMP_ULT:
+          case ICmpInst::ICMP_ULT:
+          case ICmpInst::ICMP_SLT:
+            LV = ConstantBool::getFalse();   // X < null -> always  
false
+            break;
+          case FCmpInst::FCMP_ULE:
+          case FCmpInst::FCMP_OLE:
+          case FCmpInst::FCMP_OEQ:
+          case FCmpInst::FCMP_UEQ:
+          case ICmpInst::ICMP_ULE:
+          case ICmpInst::ICMP_SLE:
+          case ICmpInst::ICMP_EQ:
+            LV = BinaryOperator::createNot(LV, "notinit", CI);
+            break;
+          case ICmpInst::ICMP_NE:
+          case ICmpInst::ICMP_UGE:
+          case ICmpInst::ICMP_SGE:
+          case ICmpInst::ICMP_UGT:
+          case ICmpInst::ICMP_SGT:
+          case FCmpInst::FCMP_FALSE:
+          case FCmpInst::FCMP_OGT:
+          case FCmpInst::FCMP_OGE:
+          case FCmpInst::FCMP_ONE:
+          case FCmpInst::FCMP_ORD:
+          case FCmpInst::FCMP_UNO:
+          case FCmpInst::FCMP_UGT:
+          case FCmpInst::FCMP_UGE:
+          case FCmpInst::FCMP_UNE:
+          case FCmpInst::FCMP_TRUE:
+            break;  // no change.
+          }
+          CI->replaceAllUsesWith(LV);
+          CI->eraseFromParent();
+        }
+        else if (SetCondInst *SCI = dyn_cast<SetCondInst> 
(LoadUse.getUser())) {
            // Replace the setcc X, 0 with a use of the bool value.


This code is walking the use list of a global variable, so all the FP  
cases (including the SetCondInst case) are dead: only pointer  
compares are possible.


@@ -746,10 +784,12 @@ static GlobalVariable *OptimizeGlobalAdd
              break;  // no change.
            }
            SCI->replaceAllUsesWith(LV);
            SCI->eraseFromParent();
          }
+        else
+          LoadUse = RepValue;
        }
        LI->eraseFromParent();


I strongly prefer that you restore this code to its original order.   
Putting the short case at the bottom makes it harder to read the  
code, even if it makes dyn_cast more natural.


Index: lib/Transforms/ExprTypeConvert.cpp
===================================================================
RCS file: /var/cvs/llvm/llvm/lib/Transforms/ExprTypeConvert.cpp,v
retrieving revision 1.115
diff -t -d -u -p -5 -r1.115 ExprTypeConvert.cpp
--- lib/Transforms/ExprTypeConvert.cpp	7 Dec 2006 01:30:31 -0000	1.115
+++ lib/Transforms/ExprTypeConvert.cpp	10 Dec 2006 23:26:40 -0000
@@ -456,10 +456,27 @@ static bool OperandConvertibleToType(Use


+  case Instruction::FCmp: {
+    FCmpInst::Predicate pred = cast<FCmpInst>(I)->getPredicate();
+    if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ ||
+        pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+      Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
+      return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
+    }
+    return false;
+  }
    case Instruction::SetEQ:
    case Instruction::SetNE: {
      Value *OtherOp = I->getOperand((V == I->getOperand(0)) ? 1 : 0);
      return ExpressionConvertibleToType(OtherOp, Ty, CTMap, TD);
    }

This code (FCmp and SetEQ/SetNE) is dead, only integer types can get  
this far.

@@ -721,10 +738,37 @@ static void ConvertOperandToType(User *U
...
      Res->setOperand(!OtherIdx, NewVal)
;+  case Instruction::FCmp: {
+    FCmpInst::Predicate pred = cast<FCmpInst>(I)->getPredicate();
+    if (pred == FCmpInst::FCMP_OEQ || pred == FCmpInst::FCMP_UEQ ||
+        pred == FCmpInst::FCMP_ONE || pred == FCmpInst::FCMP_UNE) {
+      Res = new FCmpInst(pred, Dummy, Dummy, Name);
+      VMC.ExprMap[I] = Res;  // Add node to expression eagerly
+      unsigned OtherIdx = (OldVal == I->getOperand(0)) ? 1 : 0;
+      Value *OtherOp    = I->getOperand(OtherIdx);
+      Res->setOperand(!OtherIdx, NewVal);
+      Value *NewOther   = ConvertExpressionToType(OtherOp, NewTy,  
VMC, TD);
+      Res->setOperand(OtherIdx, NewOther);
+    }
+    break;
+  }
    case Instruction::Shl:
    case Instruction::LShr:
    case Instruction::AShr:
      assert(I->getOperand(0) == OldVal);
      Res = new ShiftInst(cast<ShiftInst>(I)->getOpcode(), NewVal,

Likewise.


-Chris

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20061211/a9ef6c50/attachment.html>


More information about the llvm-commits mailing list