[gcc r16-8003] arm: Fix trapping arithmetic [PR123271]
Richard Earnshaw
rearnsha@gcc.gnu.org
Wed Mar 11 11:27:56 GMT 2026
https://gcc.gnu.org/g:f1065aba22dbf8cdf218cf60ccac310d758651e1
commit r16-8003-gf1065aba22dbf8cdf218cf60ccac310d758651e1
Author: Richard Earnshaw <rearnsha@arm.com>
Date: Wed Mar 11 11:14:47 2026 +0000
arm: Fix trapping arithmetic [PR123271]
Patch r10-3995 accidentally defined insn patterns that overrode the
default behaviour of overflow-trapping arithmetic; this broke the
implementation of -ftrapv. Fixed by renaming the internal patterns.
For consistency I've renamed more than is strictly necessary.
gcc/ChangeLog:
PR target/123271
* config/arm/arm.md (subvsi3_intmin): Renamed to ...
(sub_cmpVsi3_intmin): ... this.
(subvsi3): Renamed to ...
(sub_cmpVsi3): ... this.
(subvsi3_imm1): Renamed to ...
(sub_cmpVsi3_imm1): ... this.
(usubvsi3_borrow): Renamed to ...
(usub_cmpVsi3_borrow): ... this.
(usubvsi3_borrow_imm): Renamed to ...
(usub_cmpVsi3_borrow_imm): ... this.
(subvsi3_borrow): Renamed to ...
(sub_cmpVsi3_borrow): ... this.
(subvsi3_borrow_imm): Renamed to ...
(sub_cmpVsi3_borrow_imm): ... this.
gcc/testsuite/ChangeLog:
PR target/123271
* gcc.target/arm/pr123271.c: New test.
Diff:
---
gcc/config/arm/arm.md | 49 ++++++++++++++++++---------------
gcc/testsuite/gcc.target/arm/pr123271.c | 20 ++++++++++++++
2 files changed, 47 insertions(+), 22 deletions(-)
diff --git a/gcc/config/arm/arm.md b/gcc/config/arm/arm.md
index a3e6a362fdef..d9ce482838b0 100644
--- a/gcc/config/arm/arm.md
+++ b/gcc/config/arm/arm.md
@@ -996,7 +996,7 @@
(set_attr "type" "alus_sreg")]
)
-(define_insn "subvsi3_intmin"
+(define_insn "sub_cmpVsi3_intmin"
[(set (reg:CC_V CC_REGNUM)
(compare:CC_V
(plus:DI
@@ -1416,15 +1416,15 @@
operands[2] = GEN_INT (-INTVAL (operands[2]));
/* Special case for INT_MIN. */
if (INTVAL (operands[2]) == 0x80000000)
- emit_insn (gen_subvsi3_intmin (operands[0], operands[1]));
+ emit_insn (gen_sub_cmpVsi3_intmin (operands[0], operands[1]));
else
emit_insn (gen_addsi3_compareV_imm (operands[0], operands[1],
- operands[2]));
+ operands[2]));
}
else if (CONST_INT_P (operands[1]))
- emit_insn (gen_subvsi3_imm1 (operands[0], operands[1], operands[2]));
+ emit_insn (gen_sub_cmpVsi3_imm1 (operands[0], operands[1], operands[2]));
else
- emit_insn (gen_subvsi3 (operands[0], operands[1], operands[2]));
+ emit_insn (gen_sub_cmpVsi3 (operands[0], operands[1], operands[2]));
arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
DONE;
@@ -1497,14 +1497,16 @@
hi_op2 = force_reg (SImode, hi_op2);
rtx ccreg = gen_rtx_REG (mode, CC_REGNUM);
if (CONST_INT_P (hi_op2))
- emit_insn (gen_subvsi3_borrow_imm (hi_result, hi_op1, hi_op2,
+ emit_insn (gen_sub_cmpVsi3_borrow_imm (hi_result, hi_op1, hi_op2,
+ gen_rtx_LTU (SImode, ccreg,
+ const0_rtx),
+ gen_rtx_LTU (DImode, ccreg,
+ const0_rtx)));
+ else
+ emit_insn (gen_sub_cmpVsi3_borrow (hi_result, hi_op1, hi_op2,
gen_rtx_LTU (SImode, ccreg, const0_rtx),
gen_rtx_LTU (DImode, ccreg,
const0_rtx)));
- else
- emit_insn (gen_subvsi3_borrow (hi_result, hi_op1, hi_op2,
- gen_rtx_LTU (SImode, ccreg, const0_rtx),
- gen_rtx_LTU (DImode, ccreg, const0_rtx)));
arm_gen_unlikely_cbranch (NE, CC_Vmode, operands[3]);
DONE;
@@ -1614,15 +1616,18 @@
hi_op2 = force_reg (SImode, hi_op2);
rtx ccreg = gen_rtx_REG (mode, CC_REGNUM);
if (CONST_INT_P (hi_op2))
- emit_insn (gen_usubvsi3_borrow_imm (hi_result, hi_op1, hi_op2,
- GEN_INT (UINTVAL (hi_op2) & 0xffffffff),
+ emit_insn (gen_usub_cmpVsi3_borrow_imm (hi_result, hi_op1, hi_op2,
+ GEN_INT (UINTVAL (hi_op2)
+ & 0xffffffff),
+ gen_rtx_LTU (SImode, ccreg,
+ const0_rtx),
+ gen_rtx_LTU (DImode, ccreg,
+ const0_rtx)));
+ else
+ emit_insn (gen_usub_cmpVsi3_borrow (hi_result, hi_op1, hi_op2,
gen_rtx_LTU (SImode, ccreg, const0_rtx),
gen_rtx_LTU (DImode, ccreg,
const0_rtx)));
- else
- emit_insn (gen_usubvsi3_borrow (hi_result, hi_op1, hi_op2,
- gen_rtx_LTU (SImode, ccreg, const0_rtx),
- gen_rtx_LTU (DImode, ccreg, const0_rtx)));
arm_gen_unlikely_cbranch (LTU, CC_Bmode, operands[3]);
DONE;
@@ -1641,7 +1646,7 @@
(set_attr "type" "alus_sreg")]
)
-(define_insn "subvsi3"
+(define_insn "sub_cmpVsi3"
[(set (reg:CC_V CC_REGNUM)
(compare:CC_V
(minus:DI
@@ -1658,7 +1663,7 @@
(set_attr "type" "alus_sreg")]
)
-(define_insn "subvsi3_imm1"
+(define_insn "sub_cmpVsi3_imm1"
[(set (reg:CC_V CC_REGNUM)
(compare:CC_V
(minus:DI
@@ -2115,7 +2120,7 @@
(set_attr "type" "alus_imm")]
)
-(define_insn "usubvsi3_borrow"
+(define_insn "usub_cmpVsi3_borrow"
[(set (reg:CC_B CC_REGNUM)
(compare:CC_B
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "0,r"))
@@ -2133,7 +2138,7 @@
(set_attr "length" "2,4")]
)
-(define_insn "usubvsi3_borrow_imm"
+(define_insn "usub_cmpVsi3_borrow_imm"
[(set (reg:CC_B CC_REGNUM)
(compare:CC_B
(zero_extend:DI (match_operand:SI 1 "s_register_operand" "r,r"))
@@ -2152,7 +2157,7 @@
(set_attr "type" "alus_imm")]
)
-(define_insn "subvsi3_borrow"
+(define_insn "sub_cmpVsi3_borrow"
[(set (reg:CC_V CC_REGNUM)
(compare:CC_V
(minus:DI
@@ -2173,7 +2178,7 @@
(set_attr "length" "2,4")]
)
-(define_insn "subvsi3_borrow_imm"
+(define_insn "sub_cmpVsi3_borrow_imm"
[(set (reg:CC_V CC_REGNUM)
(compare:CC_V
(minus:DI
diff --git a/gcc/testsuite/gcc.target/arm/pr123271.c b/gcc/testsuite/gcc.target/arm/pr123271.c
new file mode 100644
index 000000000000..a1c3becceed3
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arm/pr123271.c
@@ -0,0 +1,20 @@
+/* { dg-options "-O2 -ftrapv" } */
+/* { dg-final { check-function-bodies "**" "" "" } } */
+
+int sub(int a, int b)
+{
+ return a - b;
+}
+
+/*
+** sub:
+** ...
+** (
+** bl __subvsi3
+** |
+ Not generated yet, but would be equally acceptable.
+** subs r0, r0, r1
+** bv[sc] .*
+** )
+** ...
+*/
More information about the Gcc-cvs
mailing list