diff --git a/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp b/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp --- a/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp +++ b/llvm/lib/Target/RISCV/Utils/RISCVMatInt.cpp @@ -40,6 +40,16 @@ assert(IsRV64 && "Can't emit >32-bit imm for non-RV64 target"); + // If the immediate is -1 shifted right emit the sequence ADDI+SRLI. + if (isMask_64((uint64_t)Val)) { + Res.push_back(Inst(RISCV::ADDI, -1)); + + int ShiftAmount = 64 - findLastSet((uint64_t)Val) - 1; + Res.push_back(Inst(RISCV::SRLI, ShiftAmount)); + + return; + } + // In the worst case, for a full 64-bit constant, a sequence of 8 instructions // (i.e., LUI+ADDIW+SLLI+ADDI+SLLI+ADDI+SLLI+ADDI) has to be emmitted. Note // that the first two instructions (LUI+ADDIW) can contribute up to 32 bits diff --git a/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll b/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll --- a/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll +++ b/llvm/test/CodeGen/RISCV/double-bitmanip-dagcombines.ll @@ -67,16 +67,14 @@ ; RV64I-LABEL: fabs: ; RV64I: # %bb.0: ; RV64I-NEXT: addi a1, zero, -1 -; RV64I-NEXT: slli a1, a1, 63 -; RV64I-NEXT: addi a1, a1, -1 +; RV64I-NEXT: srli a1, a1, 1 ; RV64I-NEXT: and a0, a0, a1 ; RV64I-NEXT: ret ; ; RV64IFD-LABEL: fabs: ; RV64IFD: # %bb.0: ; RV64IFD-NEXT: addi a1, zero, -1 -; RV64IFD-NEXT: slli a1, a1, 63 -; RV64IFD-NEXT: addi a1, a1, -1 +; RV64IFD-NEXT: srli a1, a1, 1 ; RV64IFD-NEXT: and a0, a0, a1 ; RV64IFD-NEXT: ret %1 = call double @llvm.fabs.f64(double %a) @@ -120,9 +118,9 @@ ; RV64I: # %bb.0: ; RV64I-NEXT: not a1, a1 ; RV64I-NEXT: addi a2, zero, -1 -; RV64I-NEXT: slli a2, a2, 63 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: addi a2, a2, -1 +; RV64I-NEXT: slli a3, a2, 63 +; RV64I-NEXT: and a1, a1, a3 +; RV64I-NEXT: srli a2, a2, 1 ; RV64I-NEXT: and a0, a0, a2 ; RV64I-NEXT: or a0, a0, a1 ; RV64I-NEXT: ret diff --git a/llvm/test/CodeGen/RISCV/double-intrinsics.ll b/llvm/test/CodeGen/RISCV/double-intrinsics.ll --- a/llvm/test/CodeGen/RISCV/double-intrinsics.ll +++ b/llvm/test/CodeGen/RISCV/double-intrinsics.ll @@ -388,8 +388,7 @@ ; RV64IFD-LABEL: fabs_f64: ; RV64IFD: # %bb.0: ; RV64IFD-NEXT: addi a1, zero, -1 -; RV64IFD-NEXT: slli a1, a1, 63 -; RV64IFD-NEXT: addi a1, a1, -1 +; RV64IFD-NEXT: srli a1, a1, 1 ; RV64IFD-NEXT: and a0, a0, a1 ; RV64IFD-NEXT: ret %1 = call double @llvm.fabs.f64(double %a) diff --git a/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll b/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll --- a/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll +++ b/llvm/test/CodeGen/RISCV/float-bit-preserving-dagcombines.ll @@ -111,8 +111,7 @@ ; RV64F-NEXT: mv s0, a0 ; RV64F-NEXT: call __adddf3 ; RV64F-NEXT: addi a1, zero, -1 -; RV64F-NEXT: slli a1, a1, 63 -; RV64F-NEXT: addi a1, a1, -1 +; RV64F-NEXT: srli a1, a1, 1 ; RV64F-NEXT: and a1, a0, a1 ; RV64F-NEXT: mv a0, s0 ; RV64F-NEXT: call __adddf3 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 @@ -132,9 +132,8 @@ ; ; RV64I-LABEL: imm64_2: ; RV64I: # %bb.0: -; RV64I-NEXT: addi a0, zero, 1 -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: addi a0, a0, -1 +; RV64I-NEXT: addi a0, zero, -1 +; RV64I-NEXT: srli a0, a0, 32 ; RV64I-NEXT: ret ret i64 4294967295 }