[PATCH] Fix problem in FP div code on IA-64

Eric Botcazou ebotcazou@adacore.com
Fri Jun 13 23:12:00 GMT 2008


Hi,

There is another problem in the new FP division code on IA-64.  Compile the 
attached Ada testcase at -O0 on Linux and you get:

/tmp/cctMsNH7.s: Assembler messages:
/tmp/cctMsNH7.s:102: Warning: Use of 'adds' may violate WAW dependency 'GR%, % 
in 1 - 127' (impliedf), specific resource number is 14
/tmp/cctMsNH7.s:101: Warning: This is the location of the conflicting usage

        frcpa.s0 f6, p6 = f6, f7
        ;;
        (p6) adds r14 = 1, r0
        (p7) adds r14 = 0, r0

The predicate register p7 is left uninitialized in the generared code.


The problem stems from the recip_approx_rf instruction:

(define_insn "recip_approx_rf"
  [(set (match_operand:RF 0 "fr_register_operand" "=f")
        (unspec:RF [(match_operand:RF 1 "fr_register_operand" "f")
		    (match_operand:RF 2 "fr_register_operand" "f")]
		   UNSPEC_FR_RECIP_APPROX_RES))
   (set (match_operand:BI 3 "register_operand" "=c")
        (unspec:BI [(match_dup 1) (match_dup 2)] UNSPEC_FR_RECIP_APPROX))
   (use (match_operand:SI 4 "const_int_operand" ""))]
  ""
  "frcpa.s%4 %0, %3 = %1, %2"
  [(set_attr "itanium_class" "fmisc")
   (set_attr "predicable" "no")])

For the testcase at hand, the instruction needs 7 reloads(!), in particular:

Reload 6: GR_REGS, RELOAD_FOR_OUTPUT_ADDRESS (opnum = 3), can't combine, 
secondary_reload_p
        reload_reg_rtx: (reg:BI 14 r14)
Reload 7: reload_out (BI) = (reg:BI 389)
        PR_REGS, RELOAD_FOR_OUTPUT (opnum = 3)
        reload_out_reg: (reg:BI 389)
        reload_reg_rtx: (reg:BI 262 p6)
        secondary_out_reload = 6

which yield

(insn 29 160 128 5 p.adb:6 (parallel [
            (set (reg:RF 134 f6)
                (unspec:RF [
                        (reg:RF 134 f6)
                        (reg:RF 135 f7)
                    ] 48))
            (set (reg:BI 262 p6)
                (unspec:BI [
                        (reg:RF 134 f6)
                        (reg:RF 135 f7)
                    ] 14))
            (use (const_int 0 [0x0]))
        ]) 490 {recip_approx_rf} (expr_list:REG_EH_REGION (const_int 1 [0x1])
        (nil)))

(note 128 29 161 6 [bb 6] NOTE_INSN_BASIC_BLOCK)

(insn 161 128 162 6 p.adb:6 (set (reg:BI 14 r14)
        (reg:BI 262 p6)) 1 {movbi} (nil))

(insn 162 161 155 6 p.adb:6 (set (mem/c:BI (reg/f:DI 111 loc79) [0 S1 A8])
        (reg:BI 14 r14)) 1 {movbi} (nil))


When the BImode splitter kicks in, insn 161 is turned into:

(insn 320 349 321 6 p.adb:6 (cond_exec (ne (reg:BI 262 p6)
            (const_int 0 [0x0]))
        (set (reg:BI 14 r14)
            (const_int 1 [0x1]))) 798 {divdf3_internal_thr+1} (nil))

(insn 321 320 350 6 p.adb:6 (cond_exec (eq (reg:BI 262 p6)
            (const_int 0 [0x0]))
        (set (reg:BI 14 r14)
            (const_int 0 [0x0]))) 798 {divdf3_internal_thr+1} (nil))

and p7 is introduced in the game without having been initialized.


The use of BImode in the instruction is incorrect since it only sets a single 
predicate register and not a pair of them.  This should be CCImode instead 
according to ia64.h:

/* ??? We say that BImode PR values require two registers.  This allows us to
   easily store the normal and inverted values.  We use CCImode to indicate
   a single predicate register.  */

#define HARD_REGNO_NREGS(REGNO, MODE)					\
  ((REGNO) == PR_REG (0) && (MODE) == DImode ? 64			\
   : PR_REGNO_P (REGNO) && (MODE) == BImode ? 2				\
   : PR_REGNO_P (REGNO) && (MODE) == CCImode ? 1			\
   : FR_REGNO_P (REGNO) && (MODE) == XFmode ? 1				\
   : FR_REGNO_P (REGNO) && (MODE) == RFmode ? 1				\
   : FR_REGNO_P (REGNO) && (MODE) == XCmode ? 2				\
   : (GET_MODE_SIZE (MODE) + UNITS_PER_WORD - 1) / UNITS_PER_WORD)


The proposed fix is attached.  Bootstrapped/regtested on ia64-suse-linux.
OK for mainline and 4.3 branch?


2008-06-13  Eric Botcazou  <ebotcazou@adacore.com>

	* config/ia64/ia64.h (HARD_REGNO_NREGS): Return 1 for CCImode
	in general purpose registers.
	(HARD_REGNO_MODE_OK): Accept CCImode in general purpose registers.
	* config/ia64/ia64.md (*movcci): Change to named pattern.  Deal
	with general purpose registers and memory operands.  Add associated
	CCImode post-reload splitter.
	* config/ia64/div.md: Change BImode to CCImode throughout.


2008-06-13  Eric Botcazou  <ebotcazou@adacore.com>

	* gnat.dg/fpdiv.adb: New test.


-- 
Eric Botcazou
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p.diff
Type: text/x-diff
Size: 7622 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080613/8eba43cd/attachment.bin>
-------------- next part --------------
A non-text attachment was scrubbed...
Name: p.adb
Type: text/x-adasrc
Size: 248 bytes
Desc: not available
URL: <http://gcc.gnu.org/pipermail/gcc-patches/attachments/20080613/8eba43cd/attachment-0001.bin>


More information about the Gcc-patches mailing list