[llvm-branch-commits] [llvm] 50c6ba7 - [RISCV] Only try LUI+SH*ADD+ADDI for int materialization if LUI+ADDI+SH*ADD failed.

Tom Stellard via llvm-branch-commits llvm-branch-commits at lists.llvm.org
Mon Apr 25 20:29:29 PDT 2022


Author: Craig Topper
Date: 2022-04-25T15:30:48-07:00
New Revision: 50c6ba751fa2c3ae8854ba09229bda62b3617c55

URL: https://github.com/llvm/llvm-project/commit/50c6ba751fa2c3ae8854ba09229bda62b3617c55
DIFF: https://github.com/llvm/llvm-project/commit/50c6ba751fa2c3ae8854ba09229bda62b3617c55.diff

LOG: [RISCV] Only try LUI+SH*ADD+ADDI for int materialization if LUI+ADDI+SH*ADD failed.

There's an assert in LUI+SH*ADD+ADDI materialization that makes sure the
lower 12 bits aren't zero since that case should have been handled as
LUI+ADDI+SH*ADD. But nothing prevented the LUI+SH*ADD+ADDI checks from
running after the earlier code handled it.

The sequence would be the same length or longer so it wouldn't replace
the earlier sequence, but the assert happened before that was checked.

The vector holding the sequence also wasn't reset before the second
check so that guaranteed the sequence would never be found to be
shorter.

This patch fixes this by only trying the second expansion when the
earlier fails.

Fixes PR54812.

Reviewed By: benshi001

Differential Revision: https://reviews.llvm.org/D123406

(cherry picked from commit 70046438d02ba1ec6bc2e2fc496b610cc1068b0f)

Added: 
    

Modified: 
    llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
    llvm/test/CodeGen/RISCV/imm.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
index e935179e5f9b0..4adcd25600f20 100644
--- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
+++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp
@@ -302,32 +302,34 @@ InstSeq generateInstSeq(int64_t Val, const FeatureBitset &ActiveFeatures) {
       TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0));
       if (TmpSeq.size() < Res.size())
         Res = TmpSeq;
-    }
-    // Try to use LUI+SH*ADD+ADDI.
-    int64_t Hi52 = ((uint64_t)Val + 0x800ull) & ~0xfffull;
-    int64_t Lo12 = SignExtend64<12>(Val);
-    Div = 0;
-    if (isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) {
-      Div = 3;
-      Opc = RISCV::SH1ADD;
-    } else if (isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) {
-      Div = 5;
-      Opc = RISCV::SH2ADD;
-    } else if (isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) {
-      Div = 9;
-      Opc = RISCV::SH3ADD;
-    }
-    // Build the new instruction sequence.
-    if (Div > 0) {
-      // For Val that has zero Lo12 (implies Val equals to Hi52) should has
-      // already been processed to LUI+SH*ADD by previous optimization.
-      assert(Lo12 != 0 &&
-             "unexpected instruction sequence for immediate materialisation");
-      generateInstSeqImpl(Hi52 / Div, ActiveFeatures, TmpSeq);
-      TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0));
-      TmpSeq.push_back(RISCVMatInt::Inst(RISCV::ADDI, Lo12));
-      if (TmpSeq.size() < Res.size())
-        Res = TmpSeq;
+    } else {
+      // Try to use LUI+SH*ADD+ADDI.
+      int64_t Hi52 = ((uint64_t)Val + 0x800ull) & ~0xfffull;
+      int64_t Lo12 = SignExtend64<12>(Val);
+      Div = 0;
+      if (isInt<32>(Hi52 / 3) && (Hi52 % 3) == 0) {
+        Div = 3;
+        Opc = RISCV::SH1ADD;
+      } else if (isInt<32>(Hi52 / 5) && (Hi52 % 5) == 0) {
+        Div = 5;
+        Opc = RISCV::SH2ADD;
+      } else if (isInt<32>(Hi52 / 9) && (Hi52 % 9) == 0) {
+        Div = 9;
+        Opc = RISCV::SH3ADD;
+      }
+      // Build the new instruction sequence.
+      if (Div > 0) {
+        // For Val that has zero Lo12 (implies Val equals to Hi52) should has
+        // already been processed to LUI+SH*ADD by previous optimization.
+        assert(Lo12 != 0 &&
+               "unexpected instruction sequence for immediate materialisation");
+        assert(TmpSeq.empty() && "Expected empty TmpSeq");
+        generateInstSeqImpl(Hi52 / Div, ActiveFeatures, TmpSeq);
+        TmpSeq.push_back(RISCVMatInt::Inst(Opc, 0));
+        TmpSeq.push_back(RISCVMatInt::Inst(RISCV::ADDI, Lo12));
+        if (TmpSeq.size() < Res.size())
+          Res = TmpSeq;
+      }
     }
   }
 

diff  --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll
index 5de49d8a7f2cb..9fa688b6f75d5 100644
--- a/llvm/test/CodeGen/RISCV/imm.ll
+++ b/llvm/test/CodeGen/RISCV/imm.ll
@@ -2401,3 +2401,39 @@ define i64 @li_rori_3() {
 ; RV64IZBS-NEXT:    ret
   ret i64 -2281701377
 }
+
+; This used to assert when compiled with Zba.
+define i64 @PR54812() {
+; RV32I-LABEL: PR54812:
+; RV32I:       # %bb.0:
+; RV32I-NEXT:    lui a0, 521599
+; RV32I-NEXT:    li a1, -1
+; RV32I-NEXT:    ret
+;
+; RV64I-LABEL: PR54812:
+; RV64I:       # %bb.0:
+; RV64I-NEXT:    lui a0, 1048447
+; RV64I-NEXT:    addiw a0, a0, 1407
+; RV64I-NEXT:    slli a0, a0, 12
+; RV64I-NEXT:    ret
+;
+; RV64IZBA-LABEL: PR54812:
+; RV64IZBA:       # %bb.0:
+; RV64IZBA-NEXT:    lui a0, 872917
+; RV64IZBA-NEXT:    sh1add a0, a0, a0
+; RV64IZBA-NEXT:    ret
+;
+; RV64IZBB-LABEL: PR54812:
+; RV64IZBB:       # %bb.0:
+; RV64IZBB-NEXT:    lui a0, 1048447
+; RV64IZBB-NEXT:    addiw a0, a0, 1407
+; RV64IZBB-NEXT:    slli a0, a0, 12
+; RV64IZBB-NEXT:    ret
+;
+; RV64IZBS-LABEL: PR54812:
+; RV64IZBS:       # %bb.0:
+; RV64IZBS-NEXT:    lui a0, 1045887
+; RV64IZBS-NEXT:    bclri a0, a0, 31
+; RV64IZBS-NEXT:    ret
+  ret i64 -2158497792;
+}


        


More information about the llvm-branch-commits mailing list