diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td @@ -939,10 +939,14 @@ def : Pat<(i64 (or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32)))), (PACKU GPR:$rs1, GPR:$rs2)>; } -let Predicates = [HasStdExtZbp] in +let Predicates = [HasStdExtZbp] in { def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFFFF), (and GPR:$rs1, 0x00FF)), (PACKH GPR:$rs1, GPR:$rs2)>; +def : Pat<(or (shl (and GPR:$rs2, 0x00FF), (XLenVT 8)), + (and GPR:$rs1, 0x00FF)), + (PACKH GPR:$rs1, GPR:$rs2)>; +} let Predicates = [HasStdExtZbbOrZbp, IsRV32] in def : Pat<(i32 (and GPR:$rs, 0xFFFF)), (ZEXTH_RV32 GPR:$rs)>; diff --git a/llvm/test/CodeGen/RISCV/rv32zbp.ll b/llvm/test/CodeGen/RISCV/rv32zbp.ll --- a/llvm/test/CodeGen/RISCV/rv32zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv32zbp.ll @@ -2937,6 +2937,26 @@ ret i32 %or } +define i32 @packh_i32_2(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: packh_i32_2: +; RV32I: # %bb.0: +; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: andi a1, a1, 255 +; RV32I-NEXT: slli a1, a1, 8 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32ZBP-LABEL: packh_i32_2: +; RV32ZBP: # %bb.0: +; RV32ZBP-NEXT: packh a0, a0, a1 +; RV32ZBP-NEXT: ret + %and = and i32 %a, 255 + %and1 = and i32 %b, 255 + %shl = shl i32 %and1, 8 + %or = or i32 %shl, %and + ret i32 %or +} + define i64 @packh_i64(i64 %a, i64 %b) nounwind { ; RV32I-LABEL: packh_i64: ; RV32I: # %bb.0: @@ -2959,6 +2979,28 @@ ret i64 %or } +define i64 @packh_i64_2(i64 %a, i64 %b) nounwind { +; RV32I-LABEL: packh_i64_2: +; RV32I: # %bb.0: +; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: andi a1, a2, 255 +; RV32I-NEXT: slli a1, a1, 8 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: li a1, 0 +; RV32I-NEXT: ret +; +; RV32ZBP-LABEL: packh_i64_2: +; RV32ZBP: # %bb.0: +; RV32ZBP-NEXT: packh a0, a0, a2 +; RV32ZBP-NEXT: li a1, 0 +; RV32ZBP-NEXT: ret + %and = and i64 %a, 255 + %and1 = and i64 %b, 255 + %shl = shl i64 %and1, 8 + %or = or i64 %shl, %and + ret i64 %or +} + define i32 @zexth_i32(i32 %a) nounwind { ; RV32I-LABEL: zexth_i32: ; RV32I: # %bb.0: diff --git a/llvm/test/CodeGen/RISCV/rv64zbp.ll b/llvm/test/CodeGen/RISCV/rv64zbp.ll --- a/llvm/test/CodeGen/RISCV/rv64zbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64zbp.ll @@ -2882,6 +2882,26 @@ ret i32 %or } +define i32 @packh_i32_2(i32 %a, i32 %b) nounwind { +; RV64I-LABEL: packh_i32_2: +; RV64I: # %bb.0: +; RV64I-NEXT: andi a0, a0, 255 +; RV64I-NEXT: andi a1, a1, 255 +; RV64I-NEXT: slli a1, a1, 8 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64ZBP-LABEL: packh_i32_2: +; RV64ZBP: # %bb.0: +; RV64ZBP-NEXT: packh a0, a0, a1 +; RV64ZBP-NEXT: ret + %and = and i32 %a, 255 + %and1 = and i32 %b, 255 + %shl = shl i32 %and1, 8 + %or = or i32 %shl, %and + ret i32 %or +} + define i64 @packh_i64(i64 %a, i64 %b) nounwind { ; RV64I-LABEL: packh_i64: ; RV64I: # %bb.0: @@ -2902,6 +2922,26 @@ ret i64 %or } +define i64 @packh_i64_2(i64 %a, i64 %b) nounwind { +; RV64I-LABEL: packh_i64_2: +; RV64I: # %bb.0: +; RV64I-NEXT: andi a0, a0, 255 +; RV64I-NEXT: andi a1, a1, 255 +; RV64I-NEXT: slli a1, a1, 8 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64ZBP-LABEL: packh_i64_2: +; RV64ZBP: # %bb.0: +; RV64ZBP-NEXT: packh a0, a0, a1 +; RV64ZBP-NEXT: ret + %and = and i64 %a, 255 + %and1 = and i64 %b, 255 + %shl = shl i64 %and1, 8 + %or = or i64 %shl, %and + ret i64 %or +} + define i32 @zexth_i32(i32 %a) nounwind { ; RV64I-LABEL: zexth_i32: ; RV64I: # %bb.0: