aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorUros Bizjak <ubizjak@gmail.com>2025-06-11 14:12:33 +0200
committerUros Bizjak <ubizjak@gmail.com>2025-06-11 16:19:57 +0200
commit76cbd678d123ed93f99c4c52456bc14290f19b7f (patch)
tree40d647ce4a630cbc813414776069bea21832ed5e
parent94e0f29b6b216a85a03b732a90f900b8b0e99c6b (diff)
downloadgcc-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.cc18
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),