[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