diff options
author | Jakub Jelinek <jakub@redhat.com> | 2021-04-27 15:46:16 +0200 |
---|---|---|
committer | Jakub Jelinek <jakub@redhat.com> | 2021-04-27 15:46:16 +0200 |
commit | 618ae596ebcd1de03857d20485d1324931852569 (patch) | |
tree | 6a5e1b4c22b78af72394a525e6a8ca5b17b2413e /gcc | |
parent | 83d26d0e1b3625ab6c2d83610a13976b52f63e0a (diff) | |
download | gcc-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.c | 6 | ||||
-rw-r--r-- | gcc/config/aarch64/aarch64.md | 5 | ||||
-rw-r--r-- | gcc/config/aarch64/predicates.md | 4 |
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") |