When investigating a builtin-arith-overflow-12.c test failure I found
the cause to be improper placement of a cbranchsi4 instruction.

In openrisc a cbranchsi4 instruction will be split to something like:

    (set (reg:BI ?sr_f)
            (cmp:BI (reg:SI x) (reg:SI y)))
    (set (pc)
            (if_then_else (eq (reg:BI ?sr_f)
                    (const_int 0 [0]))
                (label_ref:SI z)
                (pc)))

Between combine and late_combine1 optimization passes I found a case
where a cbranchsi4 was getting injected between the "set sr_f" and
"jump if sr_f" instructions.  The middle-end thought this was ok as it
could not see that the cbranchsi4 pattern will clobber the sr_f register
after splitting.

Add a clause to the cbranchsi4 pattern to indicate that it will clobber
sr_f.  This allows the middle-end to avoid placing the cbranchsi4
pattern incorrectly.

After this patch these tests pass.
  make check-gcc RUNTESTFLAGS='dg-torture.exp=builtin-arith-overflow-12.c'

gcc/ChangeLog:

        * config/or1k/or1k.md (cbranchsi4): Add clobber clause.

Signed-off-by: Stafford Horne <[email protected]>
---
 gcc/config/or1k/or1k.md | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/gcc/config/or1k/or1k.md b/gcc/config/or1k/or1k.md
index 85209a63f20..1af29f247d3 100644
--- a/gcc/config/or1k/or1k.md
+++ b/gcc/config/or1k/or1k.md
@@ -616,7 +616,8 @@
            [(match_operand:SI 1 "reg_or_0_operand" "")
             (match_operand:SI 2 "reg_or_s16_operand" "")])
          (label_ref (match_operand 3 "" ""))
-         (pc)))]
+         (pc)))
+   (clobber (reg:BI SR_F_REGNUM))]
   ""
   "#"
   "&& 1"
-- 
2.53.0


Reply via email to