Hi, The attached patch fixes PR 64793. For some reason the SH port would pretend that it can do annulled branch true insns in the delay slot of conditional branches, which then got pulled out from the delay slot by the SH reorg pass. I believe there were some misunderstandings regarding the matter. It effectively avoids using conditional branches with delay slots in some cases and as a side effect also prevents stuffing of delay slots of normal branches (which always have a delay slot).
Tested with make -k -j2 check RUNTESTFLAGS="--target_board=sh-sim \{-m2/-ml,-m2/-mb,-m2a/-mb,-m4/-ml,-m4/-mb,-m4a/-ml,-m4a/-mb}" Committed as r220772. Cheers, Oleg gcc/ChangeLog: PR target/64793 * config/sh/sh.md (cbranch define_delay): Set annulled true branch insn to nil. Adjust comments. gcc/testsuite/ChangeLog: PR target/64793 * gcc.target/sh/pr64793.c: New. * gcc.target/sh/pr51244-20-sh2a.c: Adjust expected cmp/gt insn count.
Index: gcc/testsuite/gcc.target/sh/pr64793.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr64793.c (revision 0) +++ gcc/testsuite/gcc.target/sh/pr64793.c (revision 0) @@ -0,0 +1,18 @@ +/* Check that the delay slot of an rts insn is filled, if it follows a cbranch + with an unfilled delay slot, as in: + bt .L3 + mov r7,r0 <<< this insn + rts + nop <<< should go into this delay slot +*/ +/* { dg-do compile } */ +/* { dg-options "-O2" } */ +/* { dg-final { scan-assembler-not "nop" } } */ + +int +test_0 (const char* x, int a, int b, int c) +{ + if (x[a] == 92) + return b; + return c; +} Index: gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c =================================================================== --- gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c (revision 220708) +++ gcc/testsuite/gcc.target/sh/pr51244-20-sh2a.c (working copy) @@ -8,7 +8,7 @@ /* { dg-final { scan-assembler-times "nott" 2 } } */ /* { dg-final { scan-assembler-times "cmp/eq" 2 } } */ /* { dg-final { scan-assembler-times "cmp/hi" 4 } } */ -/* { dg-final { scan-assembler-times "cmp/gt" 3 } } */ +/* { dg-final { scan-assembler-times "cmp/gt" 2 } } */ /* { dg-final { scan-assembler-not "not\t" } } */ #include "pr51244-20.c" Index: gcc/config/sh/sh.md =================================================================== --- gcc/config/sh/sh.md (revision 220708) +++ gcc/config/sh/sh.md (working copy) @@ -593,20 +593,10 @@ [(and (eq_attr "in_delay_slot" "yes") (eq_attr "type" "!pstore,prget")) (nil) (nil)]) -;; Say that we have annulled true branches, since this gives smaller and -;; faster code when branches are predicted as not taken. - -;; ??? The non-annulled condition should really be "in_delay_slot", -;; but insns that can be filled in non-annulled get priority over insns -;; that can only be filled in anulled. - +;; Conditional branches with delay slots are available starting with SH2. (define_delay - (and (eq_attr "type" "cbranch") - (match_test "TARGET_SH2")) - ;; SH2e has a hardware bug that pretty much prohibits the use of - ;; annulled delay slots. - [(eq_attr "cond_delay_slot" "yes") (and (eq_attr "cond_delay_slot" "yes") - (not (eq_attr "cpu" "sh2e"))) (nil)]) + (and (eq_attr "type" "cbranch") (match_test "TARGET_SH2")) + [(eq_attr "cond_delay_slot" "yes") (nil) (nil)]) ;; ------------------------------------------------------------------------- ;; SImode signed integer comparisons