[llvm-commits] CVS: llvm-gcc/gcc/llvm-expand.c

Chris Lattner lattner at cs.uiuc.edu
Thu Jun 17 22:48:01 PDT 2004


Changes in directory llvm-gcc/gcc:

llvm-expand.c updated: 1.41 -> 1.42

---
Log message:

Implement support for unordered comparison expressions.  This is tested
by CFrontend/2004-06-17-UnorderedBuiltins.c


---
Diffs of the changes:  (+93 -3)

Index: llvm-gcc/gcc/llvm-expand.c
diff -u llvm-gcc/gcc/llvm-expand.c:1.41 llvm-gcc/gcc/llvm-expand.c:1.42
--- llvm-gcc/gcc/llvm-expand.c:1.41	Tue Jun  8 20:10:16 2004
+++ llvm-gcc/gcc/llvm-expand.c	Thu Jun 17 22:47:02 2004
@@ -396,6 +396,46 @@
   append_inst(Fn, I);
 }
 
+/* append_llvm_isunordered_call - Emit a call to llvm.isunordered, given the two
+ * floating point argument sepecified.
+ */
+static llvm_value *append_llvm_isunordered_call(llvm_function *Fn,
+                                            llvm_value *Op1, llvm_value *Op2) {
+  llvm_instruction *I = llvm_instruction_new(BoolTy, "tmp", O_Call, 3);
+  I->Operands[1] = Op1;
+  I->Operands[2] = Op2;
+
+  assert(Op1->Ty == Op2->Ty && "Not equivalent operand types!");
+  if (Op1->Ty == FloatTy) {
+    static llvm_value *llvm_isunordered_float_fn = 0;
+    if (!llvm_isunordered_float_fn) {
+      llvm_type *FnTy = llvm_type_create_function(2, BoolTy);
+      FnTy->Elements[1] = FloatTy;
+      FnTy->Elements[2] = FloatTy;
+      FnTy = llvm_type_get_cannonical_function(FnTy);
+      llvm_isunordered_float_fn =
+        G2V(CreateIntrinsicFnWithType("llvm.isunordered", FnTy));
+    }
+
+    I->Operands[0] = llvm_isunordered_float_fn;
+  } else if (Op2->Ty == DoubleTy) {
+    static llvm_value *llvm_isunordered_double_fn = 0;
+    if (!llvm_isunordered_double_fn) {
+      llvm_type *FnTy = llvm_type_create_function(2, BoolTy);
+      FnTy->Elements[1] = DoubleTy;
+      FnTy->Elements[2] = DoubleTy;
+      FnTy = llvm_type_get_cannonical_function(FnTy);
+      llvm_isunordered_double_fn =
+        G2V(CreateIntrinsicFnWithType("llvm.isunordered", FnTy));
+    }
+
+    I->Operands[0] = llvm_isunordered_double_fn;
+  } else {
+    assert(0 && "Unknown floating point type!");
+  }
+
+  return append_inst(Fn, I);
+}
 
 /* llvm_copy_aggregate - Given two pointers to structures, copy *SrcPtr into
  * *DestPtr, element by element.
@@ -5699,6 +5739,7 @@
     InitializeComplex(Fn, DestLoc, ResultR, ResultI, 0);
 }
 
+
 /* llvm_expand_expr: generate code for computing expression EXP.  If the
  * expression produces a scalar value (which can be held in an LLVM register),
  * an llvm_value* for the computed R-value is returned.  The value is null if
@@ -6046,8 +6087,14 @@
   case TRUTH_AND_EXPR: case TRUTH_OR_EXPR: case TRUTH_XOR_EXPR: /* Bit ops */
   case LSHIFT_EXPR: case RSHIFT_EXPR:                      /* Shifts */
   case LT_EXPR: case LE_EXPR: case GT_EXPR:                /* Comparisons */
-  case GE_EXPR: case EQ_EXPR: case NE_EXPR: {              /* Comparisons */
+  case GE_EXPR: case EQ_EXPR: case NE_EXPR:                /* Comparisons */
+  case UNLT_EXPR: case UNLE_EXPR: case UNGT_EXPR: /* unordered Comparisons */
+  case UNGE_EXPR: case UNEQ_EXPR:                 /* unordered Comparisons */
+  case ORDERED_EXPR: case UNORDERED_EXPR:         /* ordered or not */
+    /* case LTGT_EXPR:   FIXME: When we merge in LTGT support from mainline */
+  {
     enum InstOpcode Opcode;
+    int isUnordered = 0;
 
     if (llvm_type_is_composite(DestTy)) {
       llvm_expand_complex_binary_expr(Fn, exp, DestLoc);
@@ -6117,6 +6164,14 @@
     case GE_EXPR:         Opcode = O_SetGE; break;
     case EQ_EXPR:         Opcode = O_SetEQ; break;
     case NE_EXPR:         Opcode = O_SetNE; break;
+    case UNLT_EXPR:         Opcode = O_SetLT; break;
+    case UNLE_EXPR:         Opcode = O_SetLE; break;
+    case UNGT_EXPR:         Opcode = O_SetGT; break;
+    case UNGE_EXPR:         Opcode = O_SetGE; break;
+    case UNEQ_EXPR:         Opcode = O_SetEQ; break;
+      /*case LTGT_EXPR:         Opcode = O_SetNE; break;  FIXME when merge */
+    case ORDERED_EXPR:    Opcode = O_Call;  break; /* SPECIAL */
+    case UNORDERED_EXPR:  Opcode = O_Call;  break; /* SPECIAL */
     case LSHIFT_EXPR:     Opcode = O_Shl;   break;
     case RSHIFT_EXPR:     Opcode = O_Shr;   break;
     default: abort();
@@ -6154,6 +6209,18 @@
     case GE_EXPR:
       break;
 
+    case UNLT_EXPR:
+    case UNLE_EXPR:
+    case UNGT_EXPR:
+    case UNGE_EXPR:
+    case UNEQ_EXPR:
+      isUnordered = 1;  /* These require an |isunordered */
+      /* case LTGT_EXPR:  FIXME WHEN MERGE */
+      break;
+    case ORDERED_EXPR:
+    case UNORDERED_EXPR:
+      break;
+
     default:
       if (Opcode < O_SetEQ && (op0->Ty->ID == PointerTyID || 
                                op1->Ty->ID == PointerTyID)) {
@@ -6181,8 +6248,31 @@
 
     if (Opcode != O_Call)
       Result = append_inst(Fn, create_binary_inst("tmp", Opcode, op0, op1));
-    else   /* Min or Max */
-      Result = llvm_expand_minmaxabs_expr(Fn, exp, op0, op1);
+    else {
+      switch (TREE_CODE(exp)) {
+      case MIN_EXPR: case MAX_EXPR:
+        Result = llvm_expand_minmaxabs_expr(Fn, exp, op0, op1);
+        break;
+      case UNORDERED_EXPR:
+        Result = append_llvm_isunordered_call(Fn, op0, op1);
+        break;
+      case ORDERED_EXPR:
+        Result = append_llvm_isunordered_call(Fn, op0, op1);
+        Result = append_inst(Fn, create_binary_inst("tmp", O_Xor, Result,
+                                                    llvm_constant_bool_true));
+        break;
+      default: abort();
+      }
+    }
+
+    /* If this is an unordered comparison, 'and` in !isunordered(X, Y). */
+    if (isUnordered) {
+      llvm_value *Tmp = append_llvm_isunordered_call(Fn, op0, op1);
+      Tmp = append_inst(Fn, create_binary_inst("tmp", O_Xor, Tmp,
+                                               llvm_constant_bool_true));
+      Result = append_inst(Fn, create_binary_inst("tmp", O_And, Tmp, Result));
+    }
+
     break;
   }
   case ABS_EXPR: {





More information about the llvm-commits mailing list