[llvm] [RISCV] Guard against out of bound shifts in expandMul. (PR #150464)

Craig Topper via llvm-commits llvm-commits at lists.llvm.org
Thu Jul 24 10:03:40 PDT 2025


https://github.com/topperc created https://github.com/llvm/llvm-project/pull/150464

Spotted while reviewing #150211. If we're multiplying by -3 in i32 MulAmt contains 4,294,967,293 since we zero extend to uint64_t. Adding 3 to this gives 0x100000000 which is a power of 2 and the log2 of that is 32, but we can't shift left by 32 in an i32.

We should use 0 instead of the shl in this case.

Normally we don't hit this case because decomeMulByConstant handles it, but that's disabled by Qciac. And after #150211 the path in expandMul will also be unreachable. So I didn't add a test to avoid messing with that review.

>From c0f2a88c2ef3903a92f715b92b3a5827e3c3ee36 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Thu, 24 Jul 2025 09:57:10 -0700
Subject: [PATCH] [RISCV] Guard against out of bound shifts in expandMul.

Spotted while reviewing #150211. If we're multiplying by -3 in i32
MulAmt contains 4,294,967,293 since we zero extend to uint64_t.
Adding 3 to this gives 0x100000000 which is a power of 2 and the log2
of that is 32, but we can't shift left by 32 in an i32.

We should use 0 instead of the shl in this case.

Normally we don't hit this case because decomeMulByConstant handles
it, but that's disabled by Qciac. And after #150211 the path in
expandMul will also be unreachable. So I didn't add a test to avoid
messing with that review.
---
 llvm/lib/Target/RISCV/RISCVISelLowering.cpp | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
index 3918dd21bc09d..25cb230785f72 100644
--- a/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelLowering.cpp
@@ -16184,10 +16184,15 @@ static SDValue expandMul(SDNode *N, SelectionDAG &DAG,
     // 2^N - 3/5/9 --> (sub (shl X, C1), (shXadd X, x))
     for (uint64_t Offset : {3, 5, 9}) {
       if (isPowerOf2_64(MulAmt + Offset)) {
+        unsigned ShAmt = Log2_64(MulAmt + Offset);
         SDLoc DL(N);
-        SDValue Shift1 =
+        SDValue Shift1;
+        if (ShAmt >= VT.getSizeInBits())
+          Shift1 = DAG.getConstant(0, DL, VT);
+        else
+          Shift1 =
             DAG.getNode(ISD::SHL, DL, VT, X,
-                        DAG.getConstant(Log2_64(MulAmt + Offset), DL, VT));
+                        DAG.getConstant(ShAmt, DL, VT));
         SDValue Mul359 =
             DAG.getNode(RISCVISD::SHL_ADD, DL, VT, X,
                         DAG.getConstant(Log2_64(Offset - 1), DL, VT), X);



More information about the llvm-commits mailing list