This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Floating point comparison


Currently, the testsuite component fp-cmp-1 (and others) fail for the
pc532-netbnsd, when optimization is off, but pass with all
optimization levels greater than -O0.

This is due to re-ordering so that 

    (jump_insn 40 39 41 (nil) (set (pc)
	    (if_then_else (lt (cc0)
		    (const_int 0 [0x0]))
		(label_ref 43)
		(pc))) -1 (nil)
	(nil))

    (jump_insn 41 40 42 (nil) (set (pc)
	    (label_ref 47)) -1 (nil)
	(nil))

    (code_label 43 42 45 20 "" [0 uses])

    (call_insn 45 43 46 (nil) (call (mem:QI (symbol_ref:SI ("abort")) [0 S1 A8])
	    (const_int 0 [0x0])) -1 (nil)
	(expr_list:REG_NORETURN (const_int 0 [0x0])
	    (expr_list:REG_EH_REGION (const_int 0 [0x0])
		(nil)))
	(nil))

    (code_label 47 46 49 19 "" [0 uses])

becomes

    (jump_insn 40 39 109 5 (nil) (set (pc)
	    (if_then_else (lt (cc0)
		    (const_int 0 [0x0]))
		(pc)
		(label_ref 47))) 162 {*bge} (nil)
	(expr_list:REG_BR_PRED (concat (const_int 8 [0x8])
		(const_int 9900 [0x26ac]))
	    (nil)))

    (call_insn 45 109 46 9 (nil) (call (mem:QI (symbol_ref:SI ("abort")) [0 S1 A8])
	    (const_int 0 [0x0])) -1 (nil)
	(expr_list:REG_NORETURN (const_int 0 [0x0])
	    (expr_list:REG_EH_REGION (const_int 0 [0x0])
		(nil)))
	(nil))

    (code_label 47 46 110 10 19 "" [1 uses])

At the machine instruction level this results in a "branch if greater
or equal" /around/ the abort instead of a "branch if less than" /to/ the abort.
The problem comes that after an ieee comparison with a NaN, bge and blt both
fail, whereas the re-ordering assumes that whenever blt is not taken, bge would
be taken. ie they are assumed to be complimentary when they are not.

The changed order first appears in whatever phase produces fp-cmp-1.c.15.bp.
I have two questions:

a) is the MI code correct in doing this re-order for floating point
   compare?  I raise the question because it never seems to happen
   when optimization is enabled.

b) I have a whole class of insn definitions which define reverse branch insn's
   of the form

        (if_then_else (...)
		(pc)
		(label_ref (match_operand 0)))

   should these be somehow disabled after floating point comparisions?
   Alternatively, I can make these reverse branches check if there was
   an unordered compare and if so, /always/ take the branch. For that
   to work reliably, I would have to be sure that these insn's are /only/ used
   when the test, as written in the users code, has been reversed.

Thanks in advance,

Ian


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]