Skip to content

Commit 7a71c1d

Browse files
rearnshaemsr
authored andcommitted
[arm] Improve constant handling for usubvsi4.
This patch improves the expansion of usubvsi4 by allowing suitable constants to be passed directly. Unlike normal subtraction, either operand may be a constant (and indeed I have seen cases where both can be with LTO enabled). One interesting testcase that improves as a result of this is: unsigned f6 (unsigned a) { unsigned x; return __builtin_sub_overflow (5U, a, &x) ? 0 : x; } Which previously compiled to: rsbs r3, r0, gcc-mirror#5 cmp r0, gcc-mirror#5 movls r0, r3 movhi r0, #0 but now generates the optimal sequence: rsbs r0, r0, gcc-mirror#5 movcc r0, #0 * config/arm/arm.md (usubv<mode>4): Delete expansion. (usubvsi4): New pattern. Allow some immediate values for inputs. (usubvdi4): New pattern. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@277187 138bc75d-0d04-0410-961f-82ee72b054a4
1 parent 190c326 commit 7a71c1d

File tree

2 files changed

+47
-5
lines changed

2 files changed

+47
-5
lines changed

gcc/ChangeLog

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
2019-10-18 Richard Earnshaw <[email protected]>
2+
3+
* config/arm/arm.md (usubv<mode>4): Delete expansion.
4+
(usubvsi4): New pattern. Allow some immediate values for inputs.
5+
(usubvdi4): New pattern.
6+
17
2019-10-18 Richard Earnshaw <[email protected]>
28

39
* config/arm/arm.c (arm_select_cc_mode): Allow either the first

gcc/config/arm/arm.md

Lines changed: 41 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1352,14 +1352,50 @@
13521352
DONE;
13531353
})
13541354

1355-
(define_expand "usubv<mode>4"
1356-
[(match_operand:SIDI 0 "register_operand")
1357-
(match_operand:SIDI 1 "register_operand")
1358-
(match_operand:SIDI 2 "register_operand")
1355+
(define_expand "usubvsi4"
1356+
[(match_operand:SI 0 "s_register_operand")
1357+
(match_operand:SI 1 "arm_rhs_operand")
1358+
(match_operand:SI 2 "arm_add_operand")
13591359
(match_operand 3 "")]
13601360
"TARGET_32BIT"
13611361
{
1362-
emit_insn (gen_sub<mode>3_compare1 (operands[0], operands[1], operands[2]));
1362+
machine_mode mode = CCmode;
1363+
if (CONST_INT_P (operands[1]) && CONST_INT_P (operands[2]))
1364+
{
1365+
/* If both operands are constants we can decide the result statically. */
1366+
wi::overflow_type overflow;
1367+
wide_int val = wi::sub (rtx_mode_t (operands[1], SImode),
1368+
rtx_mode_t (operands[2], SImode),
1369+
UNSIGNED, &overflow);
1370+
emit_move_insn (operands[0], GEN_INT (val.to_shwi ()));
1371+
if (overflow != wi::OVF_NONE)
1372+
emit_jump_insn (gen_jump (operands[3]));
1373+
DONE;
1374+
}
1375+
else if (CONST_INT_P (operands[2]))
1376+
emit_insn (gen_cmpsi2_addneg (operands[0], operands[1], operands[2],
1377+
GEN_INT (-INTVAL (operands[2]))));
1378+
else if (CONST_INT_P (operands[1]))
1379+
{
1380+
mode = CC_RSBmode;
1381+
emit_insn (gen_rsb_imm_compare (operands[0], operands[1], operands[2],
1382+
GEN_INT (~UINTVAL (operands[1]))));
1383+
}
1384+
else
1385+
emit_insn (gen_subsi3_compare1 (operands[0], operands[1], operands[2]));
1386+
arm_gen_unlikely_cbranch (LTU, mode, operands[3]);
1387+
1388+
DONE;
1389+
})
1390+
1391+
(define_expand "usubvdi4"
1392+
[(match_operand:DI 0 "s_register_operand")
1393+
(match_operand:DI 1 "s_register_operand")
1394+
(match_operand:DI 2 "s_register_operand")
1395+
(match_operand 3 "")]
1396+
"TARGET_32BIT"
1397+
{
1398+
emit_insn (gen_subdi3_compare1 (operands[0], operands[1], operands[2]));
13631399
arm_gen_unlikely_cbranch (LTU, CCmode, operands[3]);
13641400

13651401
DONE;

0 commit comments

Comments
 (0)