]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
rs6000: Add shift count guards to avoid undefined behavior [PR118890] master trunk
authorKishan Parmar <kishan@linux.ibm.com>
Fri, 22 Aug 2025 18:58:09 +0000 (00:28 +0530)
committerKishan Parmar <kishan@linux.ibm.com>
Fri, 22 Aug 2025 18:58:09 +0000 (00:28 +0530)
This patch adds missing guards on shift amounts to prevent UB when the
shift count equals or exceeds HOST_BITS_PER_WIDE_INT.

In the patch (r16-2666-g647bd0a02789f1), shift counts were only checked
for nonzero but not for being within valid bounds. This patch tightens
those conditions by enforcing that shift counts are greater than zero
and less than HOST_BITS_PER_WIDE_INT.

2025-08-23  Kishan Parmar  <kishan@linux.ibm.com>

gcc/
PR target/118890
* config/rs6000/rs6000.cc (can_be_rotated_to_negative_lis): Add bounds
checks for shift counts to prevent undefined behavior.
(rs6000_emit_set_long_const): Likewise.

gcc/config/rs6000/rs6000.cc

index 764b4992fb56485727b0bd1cda01db89d147ae80..8dd23f8619cd64cf840f876f7d6a048a81793626 100644 (file)
@@ -10322,7 +10322,7 @@ can_be_rotated_to_negative_lis (HOST_WIDE_INT c, int *rot)
      rotated over the highest bit.  */
   unsigned HOST_WIDE_INT uc = c;
   int pos_one = clz_hwi ((HOST_WIDE_INT) (uc << 16) >> 16);
-  if (pos_one != 0)
+  if (pos_one > 0 && pos_one < HOST_BITS_PER_WIDE_INT)
     {
       middle_zeros = ctz_hwi (c >> (HOST_BITS_PER_WIDE_INT - pos_one));
       int middle_ones = clz_hwi (~(uc << pos_one));
@@ -10585,7 +10585,7 @@ rs6000_emit_set_long_const (rtx dest, HOST_WIDE_INT c, int *num_insns)
     {
       /* li/lis; rldicX */
       unsigned HOST_WIDE_INT imm = (c | ~mask);
-      if (shift != 0)
+      if (shift > 0 && shift < HOST_BITS_PER_WIDE_INT)
        imm = (imm >> shift) | (imm << (HOST_BITS_PER_WIDE_INT - shift));
 
       count_or_emit_insn (temp, GEN_INT (imm));