mirror of
https://github.com/gcc-mirror/gcc.git
synced 2026-05-06 14:59:39 +02:00
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.
This commit is contained in:
@@ -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
|
||||
|
||||
20
gcc/testsuite/gcc.target/arm/pr123271.c
Normal file
20
gcc/testsuite/gcc.target/arm/pr123271.c
Normal file
@@ -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] .*
|
||||
** )
|
||||
** ...
|
||||
*/
|
||||
Reference in New Issue
Block a user