builtin-arith-overflow-3 has been failing on bfin-elf for a while. I've
had a workaround installed on the tester for a few months and I finally
got some time to dig into it over the weekend.
Ultimately I was able to nail the problem down to the representation of
the rotate left by one position instruction. I'm actually quite happy
with that result as I was briefly worried it was a deeper problem in
combine.
Essentially we're trying to synthesize a DImode shift using an SImode
rotates through CC. The key backend insn looks like:
(define_insn "rol_one"
[(set (match_operand:SI 0 "register_operand" "+d")
(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
(const_int 1))
(zero_extend:SI (reg:BI REG_CC))))
(set (reg:BI REG_CC)
(zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
""
"%0 = ROT %1 BY 1%!"
[(set_attr "type" "dsp32shiftimm")])
What the 2nd set in the pattern wants to do is indicate that CC is set
to the high bit from operand 1. But the RTL pattern is completely bogus
as it's asking for a 31 bit wide field starting at offset 0, which is
just silly for BImode. That bogus representation led combine to do some
"unexpected" transformations.
The obvious fix is to use (const_int 1) (const_int 31) in the 2nd set.
That indicates we want one bit starting at position 31.
With that pattern fixed, bfin returns to a normal state without needing
my workaround.
Installed on the trunk,
Jeff
commit 8d331aab65488b3998bd106205bbe6cab5df31b5
Author: Jeff Law <jeffreya...@gmail.com>
Date: Sun Apr 10 23:02:48 2022 -0400
[committed] Minor bfin codegen bugfix
gcc/
* config/bfin/bfin.md (rol_one): Fix pattern to indicate the
sign bit of the source ends up in CC.
diff --git a/gcc/config/bfin/bfin.md b/gcc/config/bfin/bfin.md
index 0e44653d7cb..56b24726bc2 100644
--- a/gcc/config/bfin/bfin.md
+++ b/gcc/config/bfin/bfin.md
@@ -1741,7 +1741,7 @@
(ior:SI (ashift:SI (match_operand:SI 1 "register_operand" "d")
(const_int 1))
(zero_extend:SI (reg:BI REG_CC))))
(set (reg:BI REG_CC)
- (zero_extract:BI (match_dup 1) (const_int 31) (const_int 0)))]
+ (zero_extract:BI (match_dup 1) (const_int 1) (const_int 31)))]
""
"%0 = ROT %1 BY 1%!"
[(set_attr "type" "dsp32shiftimm")])