[Bug inline-asm/56148] [4.8 Regression] inline asm matching constraint with different mode
steven at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Tue Feb 12 00:15:00 GMT 2013
http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56148
--- Comment #6 from Steven Bosscher <steven at gcc dot gnu.org> 2013-02-12 00:14:47 UTC ---
In gcc 4.7.2, reload resolved this with a pair of moves.
>From the .197r.ira and 198r.reload dumps, with the asm_operands
split out and the insns before the asm condensed, for readability:
.197r.ira_gcc472 (.208r.ira_gcc480 is identical except for insn uids):
(insn 5 (set (reg:SI 67) (const_int -1)))
(insn 6 (set (reg/f:DI 68) // and clobber flags, irrelevant
(plus:DI (reg/f:DI 20 frame) (const_int -16)))
(insn 17 6 18 2 (set (reg:DI 65 [ d ]) (reg/f:DI 68)))
(insn 18 (set (reg:SI 69) (const_int 4))) // 128>>5
(insn 10 18 0 2 (parallel [
(set (reg:DI 63 [ a ])
(asm_operands/v:DI ("") ("=d") 0 ...))
(set (reg:DI 64 [ c ])
(asm_operands/v:DI ("") ("=&c") 1 ...))
(set (reg:DI 65 [ d ])
(asm_operands/v:DI ("") ("=&D") 2 ...))
(set (reg:DI 66 [ b ])
(asm_operands/v:DI ("") ("=&a") 3 ...))
(clobber (reg:QI 18 fpsr))
(clobber (reg:QI 17 flags))
]) t.c:6 -1)
asm output operands:
[
(reg:SI 67)
(reg:DI 65 [ d ])
(reg:SI 69)
(reg:DI 65 [ d ])
(reg:SI 67)
]
asm input operands:
[
(asm_input:SI ("0") (null):0)
(asm_input:DI ("mr") (null):0)
(asm_input:SI ("1") (null):0)
(asm_input:DI ("2") (null):0)
(asm_input:SI ("3") (null):0)
]
.198r.reload_gcc472 (no gcc480 equivalent due to ICE):
(insn 5 (set (reg:SI 0 ax [67]) (const_int -1)))
(insn 17 (set (reg:DI 5 di [orig:65 d] [65])
(plus:DI (reg/f:DI 7 sp) (const_int -24))))
(insn 18 (set (reg:SI 2 cx [69]) (const_int 4)))
(insn 21 (set (reg:SI 1 dx) (reg:SI 0 ax [67]))) // reload
(insn 22 (set (reg:DI 4 si) (reg:DI 5 di [orig:65 d] [65]))) // reload
(insn 10 22 19 2 (parallel [
(set (reg:DI 1 dx [orig:63 a] [63])
(asm_operands/v:DI ("") ("=d") 0 ...))
(set (reg:DI 2 cx [orig:64 c] [64])
(asm_operands/v:DI ("") ("=&c") 1 ...))
(set (reg:DI 5 di [orig:65 d] [65])
(asm_operands/v:DI ("") ("=&D") 2 ...))
(set (reg:DI 0 ax [orig:66 b] [66])
(asm_operands/v:DI ("") ("=&a") 3 ...))
(clobber (reg:QI 18 fpsr))
(clobber (reg:QI 17 flags))
]) t.c:6 -1)
asm output operands:
[
(reg:SI 1 dx)
(reg:DI 4 si)
(reg:SI 2 cx [69])
(reg:DI 5 di [orig:65 d ] [65])
(reg:SI 0 ax [67])
]
asm input operands:
[
(asm_input:SI ("0") (null):0)
(asm_input:DI ("mr") (null):0)
(asm_input:SI ("1") (null):0)
(asm_input:DI ("2") (null):0)
(asm_input:SI ("3") (null):0)
]
LRA tries a *lot* more than just two moves:
Creates new registers:
Choosing alt 0 in insn 10: (0) =d (1) =&c (2) =&D (3) =&a (4) 0
(5) mr (6) 1 (7) 2 (8) 3
Creating newreg=73 from oldreg=63, assigning class DREG to r73
Creating newreg=74 from oldreg=65, assigning class DIREG to r74
Creating newreg=75 from oldreg=66, assigning class AREG to r75
10:
{r73:DI=asm_operands;r64:DI=asm_operands;r74:DI=asm_operands;r75:DI=asm_operands;clobber
fpsr:QI;clobber flags:QI;}
REG_DEAD r69:SI
REG_DEAD r67:SI
REG_UNUSED r66:DI
REG_UNUSED r65:DI
REG_UNUSED r64:DI
REG_UNUSED r63:DI
REG_UNUSED fpsr:QI
REG_UNUSED flags:QI
Inserting insn reload before:
20: clobber r73:DI
21: r73:DI#0=r67:SI
22: r74:DI=r65:DI
23: clobber r75:DI
24: r75:DI#0=r67:SI
The sets to the subregs of r73 and r75 are the loads of -1U which
is in r67:SI as per insn 5.
The first two of the new registers could be the same moves that reload
attempts to make, but it's difficult to tell because of the slim RTL
dumps. GDB will tell... In any case, if r64 is created for the second
move from reload (insn 22), then LRA is trying DIREG for it while reload
uses SIREG.
Next LRA tries and fails with some inheritance attempts:
Assigning to 73 (cl=DREG, orig=63, freq=3000, tfirst=73,
tfreq=3000)...
Assign 1 to reload r73 (freq=3000)
Assigning to 75 (cl=AREG, orig=66, freq=3000, tfirst=75,
tfreq=3000)...
Trying 0: spill 67(freq=3000) Now best 0(cost=-1000)
Spill r67(hr=0, freq=3000) for r75
Assign 0 to reload r75 (freq=3000)
Assigning to 74 (cl=DIREG, orig=65, freq=2000, tfirst=74,
tfreq=2000)...
Trying 5: spill 65(freq=3000) Now best 5(cost=1000)
Spill r65(hr=5, freq=3000) for r74
Assign 5 to reload r74 (freq=2000)
Assigning to 72 (cl=GENERAL_REGS, orig=72, freq=2000, tfirst=72,
tfreq=2000)...
Assign 5 to reload r72 (freq=2000)
Reassigning non-reload pseudos
Assign 4 to r65 (freq=3000)
Assign 37 to r67 (freq=3000)
Creates some more new registers for the previous new registers:
Choosing alt 0 in insn 10: (0) =d (1) =&c (2) =&D (3) =&a (4) 0
(5) mr (6) 1 (7) 2 (8) 3
Creating newreg=76 from oldreg=74, assigning class DIREG to r76
Creating newreg=77 from oldreg=75, assigning class AREG to r77
10:
{r73:DI=asm_operands;r64:DI=asm_operands;r76:DI=asm_operands;r77:DI=asm_operands;clobber
fpsr:QI;clobber flags:QI;}
REG_UNUSED r74:DI
REG_UNUSED r73:DI
REG_UNUSED r75:DI
REG_DEAD r65:DI
REG_DEAD r69:SI
REG_UNUSED r64:DI
Inserting insn reload before:
25: r76:DI=r74:DI
26: clobber r77:DI
27: r77:DI#0=r75:DI#0
Tries and fails again with some inheritance attempts, and gives up:
Assigning to 77 (cl=AREG, orig=66, freq=3000, tfirst=77,
tfreq=3000)...
Assigning to 76 (cl=DIREG, orig=65, freq=2000, tfirst=76,
tfreq=2000)...
Assign 5 to reload r76 (freq=2000)
2nd iter for reload pseudo assignments:
Reload r77 assignment failure
Spill reload r75(hr=0, freq=3000)
Spill reload r73(hr=1, freq=3000)
Spill reload r76(hr=5, freq=2000)
Assigning to 73 (cl=DREG, orig=63, freq=3000, tfirst=73,
tfreq=3000)...
Assign 1 to reload r73 (freq=3000)
Assigning to 75 (cl=AREG, orig=66, freq=3000, tfirst=75,
tfreq=3000)...
Assign 0 to reload r75 (freq=3000)
Assigning to 77 (cl=AREG, orig=66, freq=3000, tfirst=77,
tfreq=3000)...
Assigning to 76 (cl=DIREG, orig=65, freq=2000, tfirst=76,
tfreq=2000)...
Assign 5 to reload r76 (freq=2000)
Assign 0 to reload r77 (freq=3000)
deleting insn with uid = 10.
More information about the Gcc-bugs
mailing list