]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
aarch64: Fix UB in the compiler [PR100200]
authorJakub Jelinek <jakub@redhat.com>
Tue, 27 Apr 2021 13:46:16 +0000 (15:46 +0200)
committerJakub Jelinek <jakub@redhat.com>
Tue, 27 Apr 2021 13:46:16 +0000 (15:46 +0200)
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.

gcc/config/aarch64/aarch64.c
gcc/config/aarch64/aarch64.md
gcc/config/aarch64/predicates.md

index dbaf6fbe4c8f988f7d59b2847ec6884bba530150..aa148ac9de98e233813ce1032b0e925b8d0e481d 100644 (file)
@@ -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);
index abfd84526745d029ad4953eabad6dd17b159a218..aef6da9732d45b3586bad5ba57dafa438374ac3c 100644 (file)
           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))
     /* (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)
           {
index c55842b9c747b817ad8379d6f4e6dbd633ba8fe1..49f02ae0381359174fed80c2a2264295c75bc189 100644 (file)
 
 (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")