https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68277
Oleg Endo <olegendo at gcc dot gnu.org> changed:
What |Removed |Added
----------------------------------------------------------------------------
Status|UNCONFIRMED |NEW
Last reconfirmed| |2015-11-11
Ever confirmed|0 |1
--- Comment #3 from Oleg Endo <olegendo at gcc dot gnu.org> ---
(In reply to Kazumoto Kojima from comment #2)
Thanks for looking at this Kaz.
> Here is a workaround. It changes the total text size of CSiBE
> from 3310543 to 3310579 which looks simply noise.
Most of the cases go like this:
before:
mov r0,r1 <<< initial load of r1
add #-65,r1
cmp/hi r10,r1
bt/s .L345
add #-22,r1 <<< r1 reused
after:
mov r0,r1 <<< inital load of r1
add #-65,r1
cmp/hi r10,r1
mov r0,r1 <<< r1 reloaded again
bt/s .L345
add #-87,r1 <<< bigger constant
But as you said, there are only a few cases throughout CSiBE, so it doesn't
seem worth the trouble.
>
> diff --git a/gcc/config/sh/sh.md b/gcc/config/sh/sh.md
> index 557a0f0..ad39a3c 100644
> --- a/gcc/config/sh/sh.md
> +++ b/gcc/config/sh/sh.md
> @@ -2236,6 +2236,23 @@
> }
> [(set_attr "type" "arith")])
>
> +;; Old reload might generate add insns directly for the memory address
> +;; of complex insns like synchronization insns when reloading.
> +(define_insn_and_split "*addsi3"
> + [(set (match_operand:SI 0 "arith_reg_dest" "=r")
> + (plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
> + (match_operand:SI 2 "const_int_operand" "I08")))]
> + "TARGET_SH1 && !sh_lra_p ()
> + && reload_completed
> + && !reg_overlap_mentioned_p (operands[0], operands[1])"
> + "#"
> + "&& reload_completed"
> + [(set (match_dup 0) (match_dup 1))
> + (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))]
> +{
> +}
> + [(set_attr "type" "arith")])
> +
> (define_insn_and_split "*addsi3"
> [(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
> (plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r")
>
> though I'm not sure that it's ok to add that hack to fix this corner
> case.
I don't have any alternative ideas either. However, I think it's better to
also allow reg = reg + reg, instead of only allowing reg = reg + imm8:
Index: gcc/config/sh/sh.md
===================================================================
--- gcc/config/sh/sh.md (revision 230158)
+++ gcc/config/sh/sh.md (working copy)
@@ -2236,7 +2236,22 @@
}
[(set_attr "type" "arith")])
+
+;; Old reload might generate add insns directly (not through the expander) for
+;; for the memory address of complex insns like atomic insns when reloading.
(define_insn_and_split "*addsi3"
+ [(set (match_operand:SI 0 "arith_reg_dest" "=r")
+ (plus:SI (match_operand:SI 1 "arith_reg_operand" "r")
+ (match_operand:SI 2 "const_int_operand" "rI08")))]
+ "TARGET_SH1 && !sh_lra_p ()
+ && reload_completed
+ && !reg_overlap_mentioned_p (operands[0], operands[1])"
+ "#"
+ "&& 1"
+ [(set (match_dup 0) (match_dup 1))
+ (set (match_dup 0) (plus:SI (match_dup 0) (match_dup 2)))])
+
+(define_insn_and_split "*addsi3"
[(set (match_operand:SI 0 "arith_reg_dest" "=r,r")
(plus:SI (match_operand:SI 1 "arith_reg_operand" "%0,r")
(match_operand:SI 2 "arith_operand" "rI08,Z")))]
I haven't read reload.*, but my speculation is that if something in reload
instantiates that rtx with an imm8 constant to calculate addresses, it might
also try to instantiate it with reg = reg + reg if the constant doesn't fit
into imm8. Maybe we just don't hit the case (yet). So it's probably safer to
allow reg = reg + reg, too.
> There are two "new" failures with gcc testsuite:
>
> FAIL: gcc.dg/atomic/c11-atomic-exec-4.c -Os (internal compiler error)
> FAIL: gcc.dg/atomic/c11-atomic-exec-4.c -Os (test for excess errors)
>
> which is not really new because these errors have popped up randomly
> in our testresults. After all, unfortunately, some SH synchronization
> insns are too complex for the old reload. You can avoid this PR and
> c11-atomic-exec-4.c ICE with -mlra.
I guess those "new" failures are R0 related?