First Last Prev Next    No search results available
Details
: llvm-gcc tries to add bools
Bug#: 94
: tools
: llvm-g++
Status: RESOLVED
Resolution: FIXED
: Macintosh
: MacOS X
: trunk
: P2
: normal
: 1.1

:
: compile-fail
:
:
  Show dependency tree - Show dependency graph
People
Reporter: Brian R. Gaeke <gaeke+bugs@uiuc.edu>
Assigned To: Chris Lattner <sabre@nondot.org>

Attachments
proposed patch to fix Bug 94 (1.54 KB, patch)
2003-11-06 09:32, Brian R. Gaeke
Details


Note

You need to log in before you can comment on or make changes to this bug.

Related actions


Description:   Opened: 2003-11-05 18:10
While trying to build libstdc++ on Mac OS X/PowerPC:

88 cube> cat locale-inst.ii
extern bool uppercase;
int int_to_char(char *out) {
  return out[5 + uppercase];
}
89 cube> /Users/brg/cfrontend/build/gcc/xgcc locale-inst.ii
gccas: /var/tmp//ccnqZQ7C.s:218: Arithmetic operator requires integer or FP operands!
90 cube> /Users/brg/cfrontend/build/gcc/xgcc -S -o - locale-inst.ii | grep 'add bool'
        %tmp.3 = add bool %tmp.1, cast (int 5 to bool)           ; ty=bool
------- Comment #1 From Brian R. Gaeke 2003-11-05 18:35:12 -------
This is the debugging dump of the array reference: ---

 <array_ref 0x40e912b8
    type <integer_type 0x40e86380 char QI
        size <integer_cst 0x40e84140 constant 8>
        unit size <integer_cst 0x40e84154 constant 1>
        align 8 symtab 0 alias set -1 precision 8 min <integer_cst 0x40e841e0 -128> max 
<integer_cst 0x40e841f4 127>
        pointer_to_this <pointer_type 0x40e900e0>>
   
    arg 0 <parm_decl 0x40ec4e70 out
        type <pointer_type 0x40e900e0 type <integer_type 0x40e86380 char>
            unsigned SI
            size <integer_cst 0x40e849b0 constant 32>
            unit size <integer_cst 0x40e84a00 constant 4>
            align 32 symtab 0 alias set -1>
        unsigned used SI file locale-inst.ii line 2 size <integer_cst 0x40e849b0 32> unit size 
<integer_cst 0x40e84a00 4>
        align 32 context <function_decl 0x40ec4f50 int_to_char> initial <pointer_type 0x40e900e0> 
arg-type <pointer_type 0x40e900e0>>
    arg 1 <plus_expr 0x40e912a0
        type <integer_type 0x40e864d0 int SI
            size <integer_cst 0x40e84258 constant 32>
            unit size <integer_cst 0x40e842e4 constant 4>
            align 32 symtab 0 alias set -1 precision 32 min <integer_cst 0x40e842bc -2147483648> 
max <integer_cst 0x40e842d0 2147483647>
            pointer_to_this <pointer_type 0x40e95f50>>
       
        arg 0 <var_decl 0x40ec4e00 uppercase type <boolean_type 0x40e86770 bool>
            unsigned used public external decl_2 SI file locale-inst.ii line 1 size <integer_cst 
0x40e84258 32> unit size <integer_cst 0x40e842e4 4>
            align 32 chain <function_decl 0x40ec4c40 __cxa_call_unexpected>>
        arg 1 <integer_cst 0x40ebfcd0 constant 5>>>
------- Comment #2 From Brian R. Gaeke 2003-11-06 09:30:09 -------
I will upload the patch I developed for this shortly.
------- Comment #3 From Brian R. Gaeke 2003-11-06 09:32:07 -------
Created an attachment (id=5) [details]
proposed patch to fix Bug 94

With this patch, I no longer get an 'add bool' from the testcase. I am curious
to know why this never showed up on other platforms, though.
------- Comment #4 From Chris Lattner 2003-11-06 12:32:04 -------
I have no idea how this is happening on OSX: booleans should be promoted to
integers for operations like addition.

That said, here's the fix (slightly revised from Brian's patch):

$ diff -u llvm-representation.h~ llvm-representation.h
--- llvm-representation.h~      2003-10-27 11:34:07.000000000 -0600
+++ llvm-representation.h       2003-11-06 10:10:08.000000000 -0600
@@ -387,6 +387,7 @@
 #define llvm_type_is_primitive(TY) (TY->ID < FunctionTyID)
 #define llvm_type_is_fp(TY) (((TY)->ID == FloatTyID) || ((TY)->ID==DoubleTyID))
 #define llvm_type_is_integral(TY) ((TY)->ID >= BoolTyID && (TY)->ID <= LongTyID)
+#define llvm_type_is_integer(TY) ((TY)->ID > BoolTyID && (TY)->ID <= LongTyID)
 #define llvm_type_is_scalar(TY)                          \
   ((TY)->ID == PointerTyID ||                            \
    (llvm_type_is_primitive(TY) && (TY)->ID != VoidTyID))

$ diff -u llvm-representation.c~ llvm-representation.c
--- llvm-representation.c~      2003-11-04 23:46:44.000000000 -0600
+++ llvm-representation.c       2003-11-06 10:24:52.000000000 -0600
@@ -536,6 +536,9 @@
   if (Opc != O_Shr && Opc != O_Shl)
     assert(Op1->Ty == Op2->Ty &&
            "Binary operator operands must have compatible types!");
+  if (Opc == O_Add || Opc == O_Sub || Opc == O_Mul || Opc == O_Div ||
+      Opc == O_Rem)
+    assert(Ty != BoolTy && "Cannot perform arith op on boolean!");
   return New;
 }
 

$ diff -u llvm-expand.c~ llvm-expand.c
--- llvm-expand.c~      2003-11-05 10:16:59.000000000 -0600
+++ llvm-expand.c       2003-11-06 10:21:33.000000000 -0600
@@ -5187,7 +5187,7 @@
   case EXACT_DIV_EXPR:
   case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR:         /* Plus, Sub, Mult */
   case TRUNC_DIV_EXPR: case TRUNC_MOD_EXPR: case RDIV_EXPR:/* Division, Rem   */
-  case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: /* Bit operators */
+  case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: /* And, Or, Xor  */
   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 */
@@ -5212,6 +5212,22 @@
       if (V) return V;
     }
 
+    /* If this is a simple arithmetic operator, cast both operands to the result
+     * type.
+     */
+    switch (TREE_CODE(exp)) {
+    case PLUS_EXPR: case MINUS_EXPR: case MULT_EXPR:       /* Plus, Sub, Mult */
+    case TRUNC_DIV_EXPR: case TRUNC_MOD_EXPR: case RDIV_EXPR:/* Div, Rem   */
+      /* If this is not a logical operator, make sure the operands are not
+       * bools.
+       */
+      assert(DestTy != BoolTy && "Cannot produce a bool for arithetic ops!");
+    case BIT_AND_EXPR: case BIT_IOR_EXPR: case BIT_XOR_EXPR: /* And, Or, Xor */
+      op0 = cast_if_type_not_equal(Fn, op0, DestTy);
+      op1 = cast_if_type_not_equal(Fn, op1, DestTy);
+    default: break;
+    }
+
     /* Attempt to unify the types of the left and right operand... */
     if (TREE_CODE(TREE_OPERAND(exp, 1)) == INTEGER_CST)
       op1 = cast_if_type_not_equal(Fn, op1, op0->Ty);

-Chris

First Last Prev Next    No search results available