aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJakub Jelinek <jakub@redhat.com>2021-04-27 15:46:16 +0200
committerJakub Jelinek <jakub@redhat.com>2021-04-27 15:46:16 +0200
commit618ae596ebcd1de03857d20485d1324931852569 (patch)
tree6a5e1b4c22b78af72394a525e6a8ca5b17b2413e /gcc
parent83d26d0e1b3625ab6c2d83610a13976b52f63e0a (diff)
downloadgcc-618ae596ebcd1de03857d20485d1324931852569.zip
gcc-618ae596ebcd1de03857d20485d1324931852569.tar.gz
gcc-618ae596ebcd1de03857d20485d1324931852569.tar.bz2
aarch64: Fix UB in the compiler [PR100200]
The following patch fixes UBs in the compiler when negativing a CONST_INT containing HOST_WIDE_INT_MIN. I've changed the spots where there wasn't an obvious earlier condition check or predicate that would fail for such CONST_INTs. 2021-04-27 Jakub Jelinek <jakub@redhat.com> PR target/100200 * config/aarch64/predicates.md (aarch64_sub_immediate, aarch64_plus_immediate): Use -UINTVAL instead of -INTVAL. * config/aarch64/aarch64.md (casesi, rotl<mode>3): Likewise. * config/aarch64/aarch64.c (aarch64_print_operand, aarch64_split_atomic_op, aarch64_expand_subvti): Likewise.
Diffstat (limited to 'gcc')
-rw-r--r--gcc/config/aarch64/aarch64.c6
-rw-r--r--gcc/config/aarch64/aarch64.md5
-rw-r--r--gcc/config/aarch64/predicates.md4
3 files changed, 8 insertions, 7 deletions
diff --git a/gcc/config/aarch64/aarch64.c b/gcc/config/aarch64/aarch64.c
index dbaf6fb..aa148ac 100644
--- a/gcc/config/aarch64/aarch64.c
+++ b/gcc/config/aarch64/aarch64.c
@@ -10778,7 +10778,7 @@ aarch64_print_operand (FILE *f, rtx x, int code)
}
if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_INT)
- asm_fprintf (f, "%wd", -INTVAL (elt));
+ asm_fprintf (f, "%wd", -UINTVAL (elt));
else if (GET_MODE_CLASS (GET_MODE (x)) == MODE_VECTOR_FLOAT
&& aarch64_print_vector_float_operand (f, x, true))
;
@@ -21598,7 +21598,7 @@ aarch64_split_atomic_op (enum rtx_code code, rtx old_out, rtx new_out, rtx mem,
case MINUS:
if (CONST_INT_P (value))
{
- value = GEN_INT (-INTVAL (value));
+ value = GEN_INT (-UINTVAL (value));
code = PLUS;
}
/* Fall through. */
@@ -23514,7 +23514,7 @@ aarch64_expand_subvti (rtx op0, rtx low_dest, rtx low_in1,
{
if (aarch64_plus_immediate (low_in2, DImode))
emit_insn (gen_subdi3_compare1_imm (low_dest, low_in1, low_in2,
- GEN_INT (-INTVAL (low_in2))));
+ GEN_INT (-UINTVAL (low_in2))));
else
{
low_in2 = force_reg (DImode, low_in2);
diff --git a/gcc/config/aarch64/aarch64.md b/gcc/config/aarch64/aarch64.md
index abfd845..aef6da9 100644
--- a/gcc/config/aarch64/aarch64.md
+++ b/gcc/config/aarch64/aarch64.md
@@ -747,7 +747,8 @@
constant can be represented in SImode, this is important
for the corner case where operand[1] is INT_MIN. */
- operands[1] = GEN_INT (trunc_int_for_mode (-INTVAL (operands[1]), SImode));
+ operands[1]
+ = GEN_INT (trunc_int_for_mode (-UINTVAL (operands[1]), SImode));
if (!(*insn_data[CODE_FOR_addsi3].operand[2].predicate)
(operands[1], SImode))
@@ -5008,7 +5009,7 @@
/* (SZ - cnt) % SZ == -cnt % SZ */
if (CONST_INT_P (operands[2]))
{
- operands[2] = GEN_INT ((-INTVAL (operands[2]))
+ operands[2] = GEN_INT ((-UINTVAL (operands[2]))
& (GET_MODE_BITSIZE (<MODE>mode) - 1));
if (operands[2] == const0_rtx)
{
diff --git a/gcc/config/aarch64/predicates.md b/gcc/config/aarch64/predicates.md
index c55842b..49f02ae 100644
--- a/gcc/config/aarch64/predicates.md
+++ b/gcc/config/aarch64/predicates.md
@@ -121,12 +121,12 @@
(define_predicate "aarch64_sub_immediate"
(and (match_code "const_int")
- (match_test "aarch64_uimm12_shift (-INTVAL (op))")))
+ (match_test "aarch64_uimm12_shift (-UINTVAL (op))")))
(define_predicate "aarch64_plus_immediate"
(and (match_code "const_int")
(ior (match_test "aarch64_uimm12_shift (INTVAL (op))")
- (match_test "aarch64_uimm12_shift (-INTVAL (op))"))))
+ (match_test "aarch64_uimm12_shift (-UINTVAL (op))"))))
(define_predicate "aarch64_plus_operand"
(ior (match_operand 0 "register_operand")