diff options
author | Uros Bizjak <ubizjak@gmail.com> | 2025-06-11 14:12:33 +0200 |
---|---|---|
committer | Uros Bizjak <ubizjak@gmail.com> | 2025-06-11 16:19:57 +0200 |
commit | 76cbd678d123ed93f99c4c52456bc14290f19b7f (patch) | |
tree | 40d647ce4a630cbc813414776069bea21832ed5e | |
parent | 94e0f29b6b216a85a03b732a90f900b8b0e99c6b (diff) | |
download | gcc-76cbd678d123ed93f99c4c52456bc14290f19b7f.zip gcc-76cbd678d123ed93f99c4c52456bc14290f19b7f.tar.gz gcc-76cbd678d123ed93f99c4c52456bc14290f19b7f.tar.bz2 |
i386: Fix signed integer overflow in ix86_expand_int_movcc [PR120604]
Patch for PR120553 enabled full 64-bit DImode immediates in
ix86_expand_int_movcc. However, the function calculates the difference
between two immediate arguments using signed 64-bit HOST_WIDE_INT
subtractions that can cause signed integer overflow.
Avoid the overflow by casting operands of subtractions to
(unsigned HOST_WIDE_INT).
PR target/120604
gcc/ChangeLog:
* config/i386/i386-expand.cc (ix86_expand_int_movcc): Cast operands of
signed 64-bit HOST_WIDE_INT subtractions to (unsigned HOST_WIDE_INT).
-rw-r--r-- | gcc/config/i386/i386-expand.cc | 18 |
1 files changed, 12 insertions, 6 deletions
diff --git a/gcc/config/i386/i386-expand.cc b/gcc/config/i386/i386-expand.cc index 181e64a..5c8c18f 100644 --- a/gcc/config/i386/i386-expand.cc +++ b/gcc/config/i386/i386-expand.cc @@ -3609,7 +3609,7 @@ ix86_expand_int_movcc (rtx operands[]) negate_cc_compare_p = true; } - diff = ct - cf; + diff = (unsigned HOST_WIDE_INT) ct - (unsigned HOST_WIDE_INT) cf; /* Sign bit compares are better done using shifts than we do by using sbb. */ if (sign_bit_compare_p @@ -3667,7 +3667,8 @@ ix86_expand_int_movcc (rtx operands[]) PUT_CODE (compare_op, reverse_condition (GET_CODE (compare_op))); } - diff = ct - cf; + + diff = (unsigned HOST_WIDE_INT) ct - (unsigned HOST_WIDE_INT) cf; if (reg_overlap_mentioned_p (out, compare_op)) tmp = gen_reg_rtx (mode); @@ -3685,7 +3686,8 @@ ix86_expand_int_movcc (rtx operands[]) else { std::swap (ct, cf); - diff = ct - cf; + diff = (unsigned HOST_WIDE_INT) ct + - (unsigned HOST_WIDE_INT) cf; } tmp = emit_store_flag (tmp, code, op0, op1, VOIDmode, 0, -1); } @@ -3752,9 +3754,11 @@ ix86_expand_int_movcc (rtx operands[]) tmp = expand_simple_unop (mode, NOT, tmp, copy_rtx (tmp), 1); } + HOST_WIDE_INT ival = (unsigned HOST_WIDE_INT) cf + - (unsigned HOST_WIDE_INT) ct; tmp = expand_simple_binop (mode, AND, copy_rtx (tmp), - gen_int_mode (cf - ct, mode), + gen_int_mode (ival, mode), copy_rtx (tmp), 1, OPTAB_DIRECT); if (ct) tmp = expand_simple_binop (mode, PLUS, @@ -3791,7 +3795,7 @@ ix86_expand_int_movcc (rtx operands[]) if (new_code != UNKNOWN) { std::swap (ct, cf); - diff = -diff; + diff = (unsigned HOST_WIDE_INT) ct - (unsigned HOST_WIDE_INT) cf; code = new_code; } } @@ -3994,8 +3998,10 @@ ix86_expand_int_movcc (rtx operands[]) copy_rtx (out), 1, OPTAB_DIRECT); } + HOST_WIDE_INT ival = (unsigned HOST_WIDE_INT) cf + - (unsigned HOST_WIDE_INT) ct; out = expand_simple_binop (mode, AND, copy_rtx (out), - gen_int_mode (cf - ct, mode), + gen_int_mode (ival, mode), copy_rtx (out), 1, OPTAB_DIRECT); if (ct) out = expand_simple_binop (mode, PLUS, copy_rtx (out), GEN_INT (ct), |