[committed] Minor bfin codegen bugfix

Message ID 4387ce74-8d8c-9716-b489-e5d2ceace268@gmail.com
State Committed
Commit 8d331aab65488b3998bd106205bbe6cab5df31b5
Headers
Series [committed] Minor bfin codegen bugfix |

Commit Message

Jeff Law April 11, 2022, 3:06 a.m. UTC
  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 <jeffreyalaw@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.
  

Patch

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")])