diff --git a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp index badc111118727..d08115b72977f 100644 --- a/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp +++ b/llvm/lib/Target/RISCV/RISCVOptWInstrs.cpp @@ -356,6 +356,14 @@ static bool hasAllNBitUsers(const MachineInstr &OrigMI, return false; Worklist.emplace_back(UserMI, Bits); break; + case RISCV::TH_EXT: + case RISCV::TH_EXTU: + unsigned Msb = UserMI->getOperand(2).getImm(); + unsigned Lsb = UserMI->getOperand(3).getImm(); + // Behavior of Msb < Lsb is not well documented. + if (Msb >= Lsb && Bits > Msb) + break; + return false; } } } diff --git a/llvm/test/CodeGen/RISCV/bitextract-mac.ll b/llvm/test/CodeGen/RISCV/bitextract-mac.ll index 71066b2619cfa..41a32656e3257 100644 --- a/llvm/test/CodeGen/RISCV/bitextract-mac.ll +++ b/llvm/test/CodeGen/RISCV/bitextract-mac.ll @@ -107,7 +107,7 @@ define i32 @f(i32 %A, i32 %B, i32 %C) { ; ; RV64XTHEADBB-LABEL: f: ; RV64XTHEADBB: # %bb.0: # %entry -; RV64XTHEADBB-NEXT: mulw a0, a1, a0 +; RV64XTHEADBB-NEXT: mul a0, a1, a0 ; RV64XTHEADBB-NEXT: th.extu a1, a0, 5, 2 ; RV64XTHEADBB-NEXT: th.extu a0, a0, 11, 5 ; RV64XTHEADBB-NEXT: mul a0, a1, a0 @@ -116,7 +116,7 @@ define i32 @f(i32 %A, i32 %B, i32 %C) { ; ; RV64XTHEAD-LABEL: f: ; RV64XTHEAD: # %bb.0: # %entry -; RV64XTHEAD-NEXT: mulw a0, a1, a0 +; RV64XTHEAD-NEXT: mul a0, a1, a0 ; RV64XTHEAD-NEXT: th.extu a1, a0, 5, 2 ; RV64XTHEAD-NEXT: th.extu a0, a0, 11, 5 ; RV64XTHEAD-NEXT: th.mulah a2, a1, a0 diff --git a/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll b/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll index c253382d3aac9..908a12331d1bb 100644 --- a/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll +++ b/llvm/test/CodeGen/RISCV/ctlz-cttz-ctpop.ll @@ -2438,7 +2438,7 @@ define i16 @test_ctpop_i16(i16 %a) nounwind { ; RV64XTHEADBB-NEXT: and a0, a0, a2 ; RV64XTHEADBB-NEXT: add a0, a1, a0 ; RV64XTHEADBB-NEXT: srli a1, a0, 4 -; RV64XTHEADBB-NEXT: addw a0, a0, a1 +; RV64XTHEADBB-NEXT: add a0, a0, a1 ; RV64XTHEADBB-NEXT: th.extu a1, a0, 11, 8 ; RV64XTHEADBB-NEXT: andi a0, a0, 15 ; RV64XTHEADBB-NEXT: add a0, a0, a1 diff --git a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll index 4c7bd8828812f..d504d418c150b 100644 --- a/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll +++ b/llvm/test/CodeGen/RISCV/rv64xtheadbb.ll @@ -1220,3 +1220,93 @@ bb2: ; preds = %bb2, %bb bb7: ; preds = %bb2 ret void } + +define signext i32 @hasAllNBitUsers_extu(i64 %arg1, i64 %arg2, i64 %arg3) { +; RV64I-LABEL: hasAllNBitUsers_extu: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: addi a2, a2, -1 +; RV64I-NEXT: li a3, 256 +; RV64I-NEXT: .LBB38_1: # %bb2 +; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64I-NEXT: slli a0, a0, 47 +; RV64I-NEXT: srli a0, a0, 62 +; RV64I-NEXT: addi a2, a2, 1 +; RV64I-NEXT: addw a0, a0, a1 +; RV64I-NEXT: bltu a2, a3, .LBB38_1 +; RV64I-NEXT: # %bb.2: # %bb7 +; RV64I-NEXT: ret +; +; RV64XTHEADBB-LABEL: hasAllNBitUsers_extu: +; RV64XTHEADBB: # %bb.0: # %entry +; RV64XTHEADBB-NEXT: addi a2, a2, -1 +; RV64XTHEADBB-NEXT: li a3, 256 +; RV64XTHEADBB-NEXT: .LBB38_1: # %bb2 +; RV64XTHEADBB-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64XTHEADBB-NEXT: th.extu a0, a0, 16, 15 +; RV64XTHEADBB-NEXT: addi a2, a2, 1 +; RV64XTHEADBB-NEXT: addw a0, a0, a1 +; RV64XTHEADBB-NEXT: bltu a2, a3, .LBB38_1 +; RV64XTHEADBB-NEXT: # %bb.2: # %bb7 +; RV64XTHEADBB-NEXT: ret +entry: + br label %bb2 + +bb2: ; preds = %bb2, %entry + %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ] + %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ] + %i3 = add i64 %i2, 1 + %i4 = lshr i64 %i1, 15 + %i4b = and i64 %i4, 3 + %i5 = add i64 %i4b, %arg2 + %i6 = icmp ugt i64 %i2, 255 + br i1 %i6, label %bb7, label %bb2 + +bb7: ; preds = %bb2 + %i7 = trunc i64 %i5 to i32 + ret i32 %i7 +} + +define signext i32 @hasAllNBitUsers_ext(i64 %arg1, i64 %arg2, i64 %arg3) { +; RV64I-LABEL: hasAllNBitUsers_ext: +; RV64I: # %bb.0: # %entry +; RV64I-NEXT: addi a2, a2, -1 +; RV64I-NEXT: li a3, 256 +; RV64I-NEXT: .LBB39_1: # %bb2 +; RV64I-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64I-NEXT: slli a0, a0, 47 +; RV64I-NEXT: srli a0, a0, 62 +; RV64I-NEXT: addi a2, a2, 1 +; RV64I-NEXT: addw a0, a0, a1 +; RV64I-NEXT: bltu a2, a3, .LBB39_1 +; RV64I-NEXT: # %bb.2: # %bb7 +; RV64I-NEXT: ret +; +; RV64XTHEADBB-LABEL: hasAllNBitUsers_ext: +; RV64XTHEADBB: # %bb.0: # %entry +; RV64XTHEADBB-NEXT: addi a2, a2, -1 +; RV64XTHEADBB-NEXT: li a3, 256 +; RV64XTHEADBB-NEXT: .LBB39_1: # %bb2 +; RV64XTHEADBB-NEXT: # =>This Inner Loop Header: Depth=1 +; RV64XTHEADBB-NEXT: th.extu a0, a0, 16, 15 +; RV64XTHEADBB-NEXT: addi a2, a2, 1 +; RV64XTHEADBB-NEXT: addw a0, a0, a1 +; RV64XTHEADBB-NEXT: bltu a2, a3, .LBB39_1 +; RV64XTHEADBB-NEXT: # %bb.2: # %bb7 +; RV64XTHEADBB-NEXT: ret +entry: + br label %bb2 + +bb2: ; preds = %bb2, %entry + %i1 = phi i64 [ %arg1, %entry ], [ %i5, %bb2 ] + %i2 = phi i64 [ %arg3, %entry ], [ %i3, %bb2 ] + %i3 = add i64 %i2, 1 + %i4 = ashr i64 %i1, 15 + %i4b = and i64 %i4, 3 + %i5 = add i64 %i4b, %arg2 + %i6 = icmp ugt i64 %i2, 255 + br i1 %i6, label %bb7, label %bb2 + +bb7: ; preds = %bb2 + %i7 = trunc i64 %i5 to i32 + ret i32 %i7 +}