[Bug target/63949] Aarch64 instruction combiner does not optimize subsi_sxth function as expected (gcc.target/aarch64/extend.c fails)
vekumar at gcc dot gnu.org
gcc-bugzilla@gcc.gnu.org
Thu Jan 1 11:35:00 GMT 2015
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=63949
--- Comment #6 from vekumar at gcc dot gnu.org ---
In the function make_compound_operation, there a check
/* See if we have operations between an ASHIFTRT and an ASHIFT.
If so, try to merge the shifts into a SIGN_EXTEND. We could
also do this for some cases of SIGN_EXTRACT, but it doesn't
seem worth the effort; the case checked for occurs on Alpha.
*/
if (!OBJECT_P (lhs)
&& ! (GET_CODE (lhs) == SUBREG
&& (OBJECT_P (SUBREG_REG (lhs))))
&& CONST_INT_P (rhs)
&& INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
&& INTVAL (rhs) < mode_width
&& (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0)
new_rtx = make_extraction (mode, make_compound_operation (new_rtx,
next_code),
0, NULL_RTX, mode_width - INTVAL (rhs),
code == LSHIFTRT, 0, in_code == COMPARE);
break;
Our input RTL actually matches this case.
For (int)i << 1 we are getting incomming RTX as
(ashiftrt:SI (ashift:SI (reg:SI 1 x1 [ i ])
(const_int 16 [0x10]))
(const_int 15 [0xf]))
LHS is ashift:SI (reg:SI 1 x1 [ i ])
(const_int 16 [0x10])
RHS is ashiftrt with a value of 15.
So bacially we get (i<<16)>>15, we can merge these shifts to sign_extends.
With extract_left_shift we get
(ashift:SI (reg:SI 1 x1 [ i ])
(const_int 1 [0x1]))
or x1<<1
When we do make_extraction with this shift pattern we get
(ashift:SI (sign_extend:SI (reg:HI 1 x1 [ i ]))
(const_int 1 [0x1])))
But instead this we are the shift RTX, we are actually passing MULT RTX to
make_extraction via another make_compound_operation.
p make_compound_operation(new_rtx,MEM)
$3 = (rtx_def *) 0x7ffff77fd420
(gdb) pr
(mult:SI (reg:SI 1 x1 [ i ])
(const_int 2 [0x2]))
Which results in
(subreg:SI (sign_extract:DI (mult:DI (reg:DI 1 x1 [ i ])
(const_int 2 [0x2]))
(const_int 17 [0x11])
(const_int 0 [0])) 0)
When I changed the original check to
--- a/gcc/combine.c
+++ b/gcc/combine.c
@@ -7896,7 +7896,7 @@ make_compound_operation (rtx x, enum rtx_code in_code)
&& INTVAL (rhs) < HOST_BITS_PER_WIDE_INT
&& INTVAL (rhs) < mode_width
&& (new_rtx = extract_left_shift (lhs, INTVAL (rhs))) != 0)
- new_rtx = make_extraction (mode, make_compound_operation (new_rtx,
next_
+ new_rtx = make_extraction (mode, new_rtx,
0, NULL_RTX, mode_width - INTVAL (rhs),
code == LSHIFTRT, 0, in_code == COMPARE)
Combiner was able to match the pattern successfully.
Trying 8 -> 13:
Successfully matched this instruction:
(set (reg/i:SI 0 x0)
(minus:SI (reg:SI 0 x0 [ a ])
(ashift:SI (sign_extend:SI (reg:HI 1 x1 [ i ]))
(const_int 1 [0x1]))))
(minus:SI (reg:SI 0 x0 [ a ])
(ashift:SI (sign_extend:SI (reg:HI 1 x1 [ i ]))
Any comments about this change?
(const_int 1 [0x1])))
More information about the Gcc-bugs
mailing list