diff --git a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp --- a/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/MCTargetDesc/RISCVMatInt.cpp @@ -106,15 +106,28 @@ // If the remaining bits don't fit in 12 bits, we might be able to reduce the // shift amount in order to use LUI which will zero the lower 12 bits. - if (ShiftAmount > 12 && !isInt<12>(Hi52) && isInt<32>((uint64_t)Hi52 << 12)) { - // Reduce the shift amount and add zeros to the LSBs so it will match LUI. - ShiftAmount -= 12; - Hi52 = (uint64_t)Hi52 << 12; + bool Unsigned = false; + if (ShiftAmount > 12 && !isInt<12>(Hi52)) { + if (isInt<32>((uint64_t)Hi52 << 12)) { + // Reduce the shift amount and add zeros to the LSBs so it will match LUI. + ShiftAmount -= 12; + Hi52 = (uint64_t)Hi52 << 12; + } else if (isUInt<32>((uint64_t)Hi52 << 12) && + ActiveFeatures[RISCV::FeatureStdExtZba]) { + // Reduce the shift amount and add zeros to the LSBs so it will match + // LUI, then shift left with SLLI.UW to clear the upper 32 set bits. + ShiftAmount -= 12; + Hi52 = ((uint64_t)Hi52 << 12) | (0xffffffffull << 32); + Unsigned = true; + } } generateInstSeqImpl(Hi52, ActiveFeatures, Res); - Res.push_back(RISCVMatInt::Inst(RISCV::SLLI, ShiftAmount)); + if (Unsigned) + Res.push_back(RISCVMatInt::Inst(RISCV::SLLIUW, ShiftAmount)); + else + Res.push_back(RISCVMatInt::Inst(RISCV::SLLI, ShiftAmount)); if (Lo12) Res.push_back(RISCVMatInt::Inst(RISCV::ADDI, Lo12)); } diff --git a/llvm/test/CodeGen/RISCV/imm.ll b/llvm/test/CodeGen/RISCV/imm.ll --- a/llvm/test/CodeGen/RISCV/imm.ll +++ b/llvm/test/CodeGen/RISCV/imm.ll @@ -928,9 +928,8 @@ ; ; RV64IZBA-LABEL: imm_5372288229: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 160 -; RV64IZBA-NEXT: addiw a0, a0, 437 -; RV64IZBA-NEXT: slli a0, a0, 13 +; RV64IZBA-NEXT: lui a0, 655797 +; RV64IZBA-NEXT: slli.uw a0, a0, 1 ; RV64IZBA-NEXT: addi a0, a0, -795 ; RV64IZBA-NEXT: ret ; @@ -1563,9 +1562,8 @@ ; ; RV64IZBA-LABEL: imm_12900924131259: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 188 -; RV64IZBA-NEXT: addiw a0, a0, -1093 -; RV64IZBA-NEXT: slli a0, a0, 24 +; RV64IZBA-NEXT: lui a0, 768955 +; RV64IZBA-NEXT: slli.uw a0, a0, 12 ; RV64IZBA-NEXT: addi a0, a0, 1979 ; RV64IZBA-NEXT: ret ; @@ -1595,9 +1593,8 @@ ; ; RV64IZBA-LABEL: imm_50394234880: ; RV64IZBA: # %bb.0: -; RV64IZBA-NEXT: lui a0, 188 -; RV64IZBA-NEXT: addiw a0, a0, -1093 -; RV64IZBA-NEXT: slli a0, a0, 16 +; RV64IZBA-NEXT: lui a0, 768955 +; RV64IZBA-NEXT: slli.uw a0, a0, 4 ; RV64IZBA-NEXT: ret ; ; RV64IZBS-LABEL: imm_50394234880: diff --git a/llvm/test/MC/RISCV/rv64zba-aliases-valid.s b/llvm/test/MC/RISCV/rv64zba-aliases-valid.s --- a/llvm/test/MC/RISCV/rv64zba-aliases-valid.s +++ b/llvm/test/MC/RISCV/rv64zba-aliases-valid.s @@ -33,20 +33,16 @@ # CHECK-S-OBJ-NEXT: zext.w t2, t2 li x7, 0xaaaaaaaa -# CHECK-S-OBJ-NOALIAS: lui t0, 188 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t0, t0, -1093 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t0, t0, 24 +# CHECK-S-OBJ-NOALIAS: lui t0, 768955 +# CHECK-S-OBJ-NOALIAS-NEXT: slli.uw t0, t0, 12 # CHECK-S-OBJ-NOALIAS-NEXT: addi t0, t0, 1979 -# CHECK-S-OBJ: lui t0, 188 -# CHECK-S-OBJ-NEXT: addiw t0, t0, -1093 -# CHECK-S-OBJ-NEXT: slli t0, t0, 24 +# CHECK-S-OBJ: lui t0, 768955 +# CHECK-S-OBJ-NEXT: slli.uw t0, t0, 12 # CHECK-S-OBJ-NEXT: addi t0, t0, 1979 li x5, 0xbbbbb0007bb -# CHECK-S-OBJ-NOALIAS: lui t0, 188 -# CHECK-S-OBJ-NOALIAS-NEXT: addiw t0, t0, -1093 -# CHECK-S-OBJ-NOALIAS-NEXT: slli t0, t0, 16 -# CHECK-S-OBJ: lui t0, 188 -# CHECK-S-OBJ-NEXT: addiw t0, t0, -1093 -# CHECK-S-OBJ-NEXT: slli t0, t0, 16 +# CHECK-S-OBJ-NOALIAS: lui t0, 768955 +# CHECK-S-OBJ-NOALIAS-NEXT: slli.uw t0, t0, 4 +# CHECK-S-OBJ: lui t0, 768955 +# CHECK-S-OBJ-NEXT: slli.uw t0, t0, 4 li x5, 0xbbbbb0000