Chris,

I rewrote the llvm-gcc portion of the SETCC patch with your suggestions.
It is much cleaner now. The patch is attached. Hopefully this is more to
your liking.

Reid.

Sheng: This is just FYI.

On Sun, 2006-12-10 at 18:03 -0800, Chris Lattner wrote:
> On Dec 10, 2006, at 3:43 PM, Reid Spencer wrote:
> > Here's the SETCC patch to convert SetCondInst (SetCC) instructions
> > into
> > ICmpInst. Here's somethings you should know about this patch:
> > 
> > 
> > 3. The SetCondInst instruction is still used for floating point
> > comparisons.
> 
> 
> Ok, this will be changed in the next patch?
> 
> 
> > 6. The llvm-gcc patch emits ICmp for integer/pointer and SetCC for
> > floating 
> >    point. No FCmpInst instructions are emitted. We'll do that in the
> > next patch.
> 
> 
> Ok, sounds great.
> 
> 
> For the llvm-gcc patch:
> 
> 
>    Value *EmitCompare(tree_node *exp, unsigned Opc, bool isUnordered);
> +  Value *EmitCompare(tree_node *exp, unsigned Opc);
> 
> 
> I don't like the subtle overloads here.  One way to fix this:
> 
> 
> +  case LT_EXPR: {
> +    tree Op0Ty = TREE_TYPE(TREE_OPERAND(exp,0));
> +    if (!FLOAT_TYPE_P(Op0Ty))
> +      Result = 
> +        EmitCompare(exp, TYPE_UNSIGNED(Op0Ty) ? 
> +                    ICmpInst::ICMP_ULT : ICmpInst::ICMP_SLT);
> +    else 
> +      Result = EmitCompare(exp, Instruction::SetLT, 0); 
> +    break;
> +  }
> +  case LE_EXPR: {
> +    tree Op0Ty = TREE_TYPE(TREE_OPERAND(exp,0));
> +    if (!FLOAT_TYPE_P(Op0Ty))
> +      Result = 
> +        EmitCompare(exp, TYPE_UNSIGNED(Op0Ty) ? 
> +                    ICmpInst::ICMP_ULE : ICmpInst::ICMP_SLE);
> +    else 
> +      Result = EmitCompare(exp, Instruction::SetLE, 0); 
> +    break;
> +  }
> 
> 
> This logic shouldn't be duplicated everywhere.  I much prefer that you
> do something like:
> 
> 
> case LT_EXPR:
>   Result = EmitCompare(exp, ICmpInst::ICMP_ULT,
> ICmpInst::ICMP_SLT, Instruction::SetLT, 0);
>   break;
> 
> 
> ... and move the code for determining which opcode to use into
> EmitCompare.  The same can be
> done for EmitMinMaxExpr.
> 
> 
> 
> 
> @@ -2261,8 +2319,8 @@
>    Value *Op = Emit(TREE_OPERAND(exp, 0), 0);
>    if (!Op->getType()->isFloatingPoint()) {
>      Instruction *OpN = BinaryOperator::createNeg(Op,
> Op->getName()+"neg",CurBB);
> -    Value *Cmp = new SetCondInst(Instruction::SetGE, Op,
> OpN->getOperand(0),
> -                                 "abscond", CurBB);
> +    Value *Cmp = new ICmpInst(ICmpInst::ICMP_SGE, Op,
> OpN->getOperand(0), 
> +                              "abscond", CurBB);
>      return new SelectInst(Cmp, Op, OpN, "abs", CurBB);
>    } else {
>      // Turn FP abs into fabs/fabsf.
> 
> 
> This isn't right.  You need to emit a signed or unsigned comparison
> depending on TYPE_UNSIGNED.  It would make sense to just use a call to
> EmitCompare here and have it pick the right one.  I know that unsigned
> abs doesn't make much sense, but this is how expr.c handles it for
> GCC:
> 
> 
>       /* Unsigned abs is simply the operand.  Testing here means we
> don't
>          risk generating incorrect code below.  */
>       if (TYPE_UNSIGNED (type))
>         return op0;
> 
> 
> @@ -2464,8 +2542,13 @@
>    LHS = NOOPCastToType(LHS, Ty);
>    RHS = NOOPCastToType(RHS, Ty);
> 
>    
> 
> 
> -  Value *Pred = new SetCondInst((Instruction::BinaryOps)CmpOpc, LHS,
> RHS,
> -                                "tmp", CurBB);
> +  Value *Pred;
> +  if (LHS->getType()->isFloatingPoint())
> +    Pred = new SetCondInst((Instruction::BinaryOps)CmpOpc, LHS, RHS,
> +                           "tmp", CurBB);
> +  else
> +    Pred = new ICmpInst((ICmpInst::Predicate)CmpOpc, LHS, RHS, 
> +                             "tmp", CurBB);
>    return new SelectInst(Pred, LHS, RHS,
>                          TREE_CODE(exp) == MAX_EXPR ? "max" : "min",
> CurBB);
>  }
> 
> 
> Likewise this code is wrong (for max).  It should also just call
> EmitCompare.
> 
> 
> -Chris
Index: gcc/llvm-convert.cpp
===================================================================
--- gcc/llvm-convert.cpp	(revision 225)
+++ gcc/llvm-convert.cpp	(working copy)
@@ -537,23 +537,35 @@
   case TRUTH_NOT_EXPR: Result = EmitTRUTH_NOT_EXPR(exp); break;
 
   // Binary Operators
-  case LT_EXPR:        Result = EmitCompare(exp, Instruction::SetLT, 0); break;
-  case LE_EXPR:        Result = EmitCompare(exp, Instruction::SetLE, 0); break;
-  case GT_EXPR:        Result = EmitCompare(exp, Instruction::SetGT, 0); break;
-  case GE_EXPR:        Result = EmitCompare(exp, Instruction::SetGE, 0); break;
-  case EQ_EXPR:        Result = EmitCompare(exp, Instruction::SetEQ, 0); break;
-  case NE_EXPR:        Result = EmitCompare(exp, Instruction::SetNE, 0); break;
-  case UNORDERED_EXPR: Result = EmitCompare(exp, 0, 1); break; // not a typo
-  case ORDERED_EXPR:   Result = EmitCompare(exp, 0, 1); break; // not a typo
-  case UNLT_EXPR:      Result = EmitCompare(exp, Instruction::SetLT, 1); break;
-  case UNLE_EXPR:      Result = EmitCompare(exp, Instruction::SetLE, 1); break;
-  case UNGT_EXPR:      Result = EmitCompare(exp, Instruction::SetGT, 1); break;
-  case UNGE_EXPR:      Result = EmitCompare(exp, Instruction::SetGE, 1); break;
-  case UNEQ_EXPR:      Result = EmitCompare(exp, Instruction::SetEQ, 1); break;
-  case LTGT_EXPR:      Result = EmitCompare(exp, Instruction::SetNE, 1); break;
-  case PLUS_EXPR:      Result = EmitBinOp(exp, DestLoc, Instruction::Add);break;
-  case MINUS_EXPR:     Result = EmitBinOp(exp, DestLoc, Instruction::Sub);break;
-  case MULT_EXPR:      Result = EmitBinOp(exp, DestLoc, Instruction::Mul);break;
+  case LT_EXPR: 
+    Result = EmitCompare(exp, ICmpInst::ICMP_ULT, ICmpInst::ICMP_SLT, 
+                         Instruction::SetLT, 0); break;
+  case LE_EXPR:
+    Result = EmitCompare(exp, ICmpInst::ICMP_ULE, ICmpInst::ICMP_SLE,
+                         Instruction::SetLE, 0); break;
+  case GT_EXPR:
+    Result = EmitCompare(exp, ICmpInst::ICMP_UGT, ICmpInst::ICMP_SGT,
+                         Instruction::SetGT, 0); break;
+  case GE_EXPR:
+    Result = EmitCompare(exp, ICmpInst::ICMP_UGE, ICmpInst::ICMP_SGE, 
+                         Instruction::SetGE, 0); break;
+  case EQ_EXPR:
+    Result = EmitCompare(exp, ICmpInst::ICMP_EQ, ICmpInst::ICMP_EQ, 
+                         Instruction::SetEQ, 0); break;
+  case NE_EXPR:
+    Result = EmitCompare(exp, ICmpInst::ICMP_NE, ICmpInst::ICMP_NE, 
+                         Instruction::SetNE, 0); break;
+  case UNORDERED_EXPR: Result = EmitCompare(exp, 0, 0, 0, 1); break;// not typo 
+  case ORDERED_EXPR:   Result = EmitCompare(exp, 0, 0, 0, 1); break;// not typo 
+  case UNLT_EXPR: Result = EmitCompare(exp, 0, 0, Instruction::SetLT, 1); break;
+  case UNLE_EXPR: Result = EmitCompare(exp, 0, 0, Instruction::SetLE, 1); break;
+  case UNGT_EXPR: Result = EmitCompare(exp, 0, 0, Instruction::SetGT, 1); break;
+  case UNGE_EXPR: Result = EmitCompare(exp, 0, 0, Instruction::SetGE, 1); break;
+  case UNEQ_EXPR: Result = EmitCompare(exp, 0, 0, Instruction::SetEQ, 1); break;
+  case LTGT_EXPR: Result = EmitCompare(exp, 0, 0, Instruction::SetNE, 1); break;
+  case PLUS_EXPR: Result = EmitBinOp(exp, DestLoc, Instruction::Add);break;
+  case MINUS_EXPR:Result = EmitBinOp(exp, DestLoc, Instruction::Sub);break;
+  case MULT_EXPR: Result = EmitBinOp(exp, DestLoc, Instruction::Mul);break;
   case TRUNC_DIV_EXPR: 
     if (TYPE_UNSIGNED(TREE_TYPE(exp)))
       Result = EmitBinOp(exp, DestLoc, Instruction::UDiv);
@@ -589,8 +601,14 @@
   case LROTATE_EXPR:
     Result = EmitRotateOp(exp, Instruction::Shl, Instruction::LShr);
     break;
-  case MIN_EXPR:       Result = EmitMinMaxExpr(exp, Instruction::SetLE); break;
-  case MAX_EXPR:       Result = EmitMinMaxExpr(exp, Instruction::SetGE); break;
+  case MIN_EXPR: 
+    Result = EmitMinMaxExpr(exp, ICmpInst::ICMP_ULE, ICmpInst::ICMP_SLE, 
+                            Instruction::SetLE);
+    break;
+  case MAX_EXPR:
+    Result = EmitMinMaxExpr(exp, ICmpInst::ICMP_UGE, ICmpInst::ICMP_SGE,
+                            Instruction::SetGE);
+    break;
   case CONSTRUCTOR:    Result = EmitCONSTRUCTOR(exp, DestLoc); break;
     
   // Complex Math Expressions.
@@ -2269,8 +2287,9 @@
   Value *Op = Emit(TREE_OPERAND(exp, 0), 0);
   if (!Op->getType()->isFloatingPoint()) {
     Instruction *OpN = BinaryOperator::createNeg(Op, Op->getName()+"neg",CurBB);
-    Value *Cmp = new SetCondInst(Instruction::SetGE, Op, OpN->getOperand(0),
-                                 "abscond", CurBB);
+    ICmpInst::Predicate pred = TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp,0))) ?
+      ICmpInst::ICMP_UGE : ICmpInst::ICMP_SGE;
+    Value *Cmp = new ICmpInst(pred, Op, OpN->getOperand(0), "abscond", CurBB);
     return new SelectInst(Cmp, Op, OpN, "abs", CurBB);
   } else {
     // Turn FP abs into fabs/fabsf.
@@ -2295,20 +2314,38 @@
 /// comparison to use.  isUnord is true if this is a floating point comparison
 /// that should also be true if either operand is a NaN.  Note that Opc can be
 /// set to zero for special cases.
-Value *TreeToLLVM::EmitCompare(tree exp, unsigned Opc, bool isUnord) {
-  if (TREE_CODE(TREE_TYPE(TREE_OPERAND(exp, 0))) == COMPLEX_TYPE)
-    return EmitComplexBinOp(exp, 0);  // Complex ==/!=
-  
-  // Comparison of struct is not allowed, so this is safe.
+Value *TreeToLLVM::EmitCompare(tree exp, unsigned UIOpc, unsigned SIOpc, 
+                               unsigned FPOpc, bool isUnord) {
+  // Get the type of the operands
+  tree Op0Ty = TREE_TYPE(TREE_OPERAND(exp,0));
+
+  // Get the compare operands, in the right type. Comparison of struct is not
+  // allowed, so this is safe.
   Value *LHS = Emit(TREE_OPERAND(exp, 0), 0);
   Value *RHS = Emit(TREE_OPERAND(exp, 1), 0);
   RHS = NOOPCastToType(RHS, LHS->getType());
-  
   assert(LHS->getType() == RHS->getType() && "Binop type equality failure!");
+
+  // Handle the integer/pointer cases
+  if (!FLOAT_TYPE_P(Op0Ty)) {
+    // Determine which predicate to use based on signedness
+    ICmpInst::Predicate pred = 
+      ICmpInst::Predicate(TYPE_UNSIGNED(Op0Ty) ? UIOpc : SIOpc);
+
+    // Get the compare instructions
+    Value *Result = new ICmpInst(pred, LHS, RHS, "tmp", CurBB);
+    
+    // The GCC type is probably an int, not a bool.
+    return CastToType(Result, ConvertType(TREE_TYPE(exp)));
+  }
+
+  // Handle floating point comparisons, if we get here.
+  if (TREE_CODE(Op0Ty) == COMPLEX_TYPE)
+    return EmitComplexBinOp(exp, 0);  // Complex ==/!=
   
   Value *Result = 0;
-  if (Opc)
-    Result = new SetCondInst((Instruction::BinaryOps)Opc, LHS, RHS, "tmp",
+  if (FPOpc)
+    Result = new SetCondInst((Instruction::BinaryOps)FPOpc, LHS, RHS, "tmp",
                              CurBB);
   
   if (isUnord) {
@@ -2329,7 +2366,7 @@
       Result = IsUnord;
     
     // If this is an ORDERED_EXPR, invert the result of the isunordered call.
-    if (Opc == ORDERED_EXPR)
+    if (FPOpc == ORDERED_EXPR)
       Result = BinaryOperator::createNot(Result, "tmp", CurBB);
   }
   
@@ -2464,7 +2501,8 @@
   return CastToType(Merge, ConvertType(TREE_TYPE(exp)));
 }
 
-Value *TreeToLLVM::EmitMinMaxExpr(tree exp, unsigned CmpOpc) {
+Value *TreeToLLVM::EmitMinMaxExpr(tree exp, unsigned UIPred, unsigned SIPred, 
+                                  unsigned FPOpc) {
   Value *LHS = Emit(TREE_OPERAND(exp, 0), 0);
   Value *RHS = Emit(TREE_OPERAND(exp, 1), 0);
 
@@ -2472,9 +2510,16 @@
   LHS = NOOPCastToType(LHS, Ty);
   RHS = NOOPCastToType(RHS, Ty);
   
-  Value *Pred = new SetCondInst((Instruction::BinaryOps)CmpOpc, LHS, RHS,
-                                "tmp", CurBB);
-  return new SelectInst(Pred, LHS, RHS,
+  Value *Compare;
+  if (LHS->getType()->isFloatingPoint())
+    Compare = new SetCondInst((Instruction::BinaryOps)FPOpc, LHS, RHS,
+                           "tmp", CurBB);
+  else if TYPE_UNSIGNED(TREE_TYPE(TREE_OPERAND(exp, 0)))
+    Compare = new ICmpInst(ICmpInst::Predicate(UIPred), LHS, RHS, "tmp", CurBB);
+  else
+    Compare = new ICmpInst(ICmpInst::Predicate(SIPred), LHS, RHS, "tmp", CurBB);
+
+  return new SelectInst(Compare, LHS, RHS,
                         TREE_CODE(exp) == MAX_EXPR ? "max" : "min", CurBB);
 }
 
Index: gcc/llvm-internal.h
===================================================================
--- gcc/llvm-internal.h	(revision 225)
+++ gcc/llvm-internal.h	(working copy)
@@ -388,13 +388,15 @@
   Value *EmitABS_EXPR(tree_node *exp);
   Value *EmitBIT_NOT_EXPR(tree_node *exp);
   Value *EmitTRUTH_NOT_EXPR(tree_node *exp);
-  Value *EmitCompare(tree_node *exp, unsigned Opc, bool isUnordered);
+  Value *EmitCompare(tree_node *exp, unsigned UIPred, unsigned SIPred, 
+                     unsigned FPOpc, bool isUnordered);
   Value *EmitBinOp(tree_node *exp, Value *DestLoc, unsigned Opc);
   Value *EmitPtrBinOp(tree_node *exp, unsigned Opc);
   Value *EmitTruthOp(tree_node *exp, unsigned Opc);
   Value *EmitShiftOp(tree_node *exp, Value *DestLoc, unsigned Opc);
   Value *EmitRotateOp(tree_node *exp, unsigned Opc1, unsigned Opc2);
-  Value *EmitMinMaxExpr(tree_node *exp, unsigned Opc);
+  Value *EmitMinMaxExpr(tree_node *exp, unsigned UIPred, unsigned SIPred, 
+                        unsigned Opc);
 
   // Inline Assembly and Register Variables.
   Value *EmitASM_EXPR(tree_node *exp);
_______________________________________________
llvm-commits mailing list
llvm-commits@cs.uiuc.edu
http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits

Reply via email to