diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td --- a/llvm/lib/Target/RISCV/RISCVInstrInfoB.td +++ b/llvm/lib/Target/RISCV/RISCVInstrInfoB.td @@ -356,19 +356,17 @@ def BCOMPRESS : ALU_rr<0b0000100, 0b110, "bcompress">, Sched<[]>; } // Predicates = [HasStdExtZbe] -let Predicates = [HasStdExtZbbOrZbp] in { +let Predicates = [HasStdExtZbp] in { def PACK : ALU_rr<0b0000100, 0b100, "pack">, Sched<[]>; def PACKU : ALU_rr<0b0100100, 0b100, "packu">, Sched<[]>; -} // Predicates = [HasStdExtZbbOrZbp] +def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>; +} // Predicates = [HasStdExtZbp] let Predicates = [HasStdExtZbm, IsRV64] in { def BMATOR : ALU_rr<0b0000100, 0b011, "bmator">, Sched<[]>; def BMATXOR : ALU_rr<0b0100100, 0b011, "bmatxor">, Sched<[]>; } // Predicates = [HasStdExtZbm, IsRV64] -let Predicates = [HasStdExtZbbOrZbp] in -def PACKH : ALU_rr<0b0000100, 0b111, "packh">, Sched<[]>; - let Predicates = [HasStdExtZbf] in def BFP : ALU_rr<0b0100100, 0b111, "bfp">, Sched<[]>; @@ -459,10 +457,10 @@ def BCOMPRESSW : ALUW_rr<0b0000100, 0b110, "bcompressw">, Sched<[]>; } // Predicates = [HasStdExtZbe, IsRV64] -let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { +let Predicates = [HasStdExtZbp, IsRV64] in { def PACKW : ALUW_rr<0b0000100, 0b100, "packw">, Sched<[]>; def PACKUW : ALUW_rr<0b0100100, 0b100, "packuw">, Sched<[]>; -} // Predicates = [HasStdExtZbbOrZbp, IsRV64] +} // Predicates = [HasStdExtZbp, IsRV64] let Predicates = [HasStdExtZbf, IsRV64] in def BFPW : ALUW_rr<0b0100100, 0b111, "bfpw">, Sched<[]>; @@ -502,11 +500,11 @@ // Pseudo Instructions //===----------------------------------------------------------------------===// -let Predicates = [HasStdExtZbb, IsRV32] in { +let Predicates = [HasStdExtZbp, IsRV32] in { def : InstAlias<"zext.h $rd, $rs", (PACK GPR:$rd, GPR:$rs, X0)>; } // Predicates = [HasStdExtZbb, IsRV32] -let Predicates = [HasStdExtZbb, IsRV64] in { +let Predicates = [HasStdExtZbp, IsRV64] in { def : InstAlias<"zext.h $rd, $rs", (PACKW GPR:$rd, GPR:$rs, X0)>; } // Predicates = [HasStdExtZbb, IsRV64] @@ -790,26 +788,26 @@ def : Pat<(umax GPR:$rs1, GPR:$rs2), (MAXU GPR:$rs1, GPR:$rs2)>; } // Predicates = [HasStdExtZbb] -let Predicates = [HasStdExtZbbOrZbp, IsRV32] in +let Predicates = [HasStdExtZbp, IsRV32] in def : Pat<(or (and GPR:$rs1, 0x0000FFFF), (shl GPR:$rs2, (i32 16))), (PACK GPR:$rs1, GPR:$rs2)>; -let Predicates = [HasStdExtZbbOrZbp, IsRV64] in +let Predicates = [HasStdExtZbp, IsRV64] in def : Pat<(or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32))), (PACK GPR:$rs1, GPR:$rs2)>; -let Predicates = [HasStdExtZbbOrZbp, IsRV32] in +let Predicates = [HasStdExtZbp, IsRV32] in def : Pat<(or (and GPR:$rs2, 0xFFFF0000), (srl GPR:$rs1, (i32 16))), (PACKU GPR:$rs1, GPR:$rs2)>; -let Predicates = [HasStdExtZbbOrZbp, IsRV64] in +let Predicates = [HasStdExtZbp, IsRV64] in def : Pat<(or (and GPR:$rs2, 0xFFFFFFFF00000000), (srl GPR:$rs1, (i64 32))), (PACKU GPR:$rs1, GPR:$rs2)>; -let Predicates = [HasStdExtZbbOrZbp] in +let Predicates = [HasStdExtZbp] in def : Pat<(or (and (shl GPR:$rs2, (XLenVT 8)), 0xFF00), (and GPR:$rs1, 0x00FF)), (PACKH GPR:$rs1, GPR:$rs2)>; -let Predicates = [HasStdExtZbbOrZbp, IsRV32] in +let Predicates = [HasStdExtZbp, IsRV32] in def : Pat<(and GPR:$rs, 0x0000FFFF), (PACK GPR:$rs, X0)>; -let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { +let Predicates = [HasStdExtZbp, IsRV64] in { def : Pat<(and GPR:$rs, 0x000000000000FFFF), (PACKW GPR:$rs, X0)>; } @@ -949,7 +947,7 @@ def : Pat<(ctpop (and GPR:$rs1, (i64 0xFFFFFFFF))), (CPOPW GPR:$rs1)>; } // Predicates = [HasStdExtZbb, IsRV64] -let Predicates = [HasStdExtZbbOrZbp, IsRV64] in { +let Predicates = [HasStdExtZbp, IsRV64] in { def : Pat<(sext_inreg (or (shl GPR:$rs2, (i64 16)), (and GPR:$rs1, 0x000000000000FFFF)), i32), @@ -958,4 +956,4 @@ (srl (and GPR:$rs1, 0x00000000FFFF0000), (i64 16))), (PACKUW GPR:$rs1, GPR:$rs2)>; -} // Predicates = [HasStdExtZbbOrZbp, IsRV64] +} // Predicates = [HasStdExtZbp, IsRV64] diff --git a/llvm/test/CodeGen/RISCV/rv32Zbbp.ll b/llvm/test/CodeGen/RISCV/rv32Zbbp.ll --- a/llvm/test/CodeGen/RISCV/rv32Zbbp.ll +++ b/llvm/test/CodeGen/RISCV/rv32Zbbp.ll @@ -744,252 +744,3 @@ %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63) ret i64 %1 } - -define i32 @pack_i32(i32 %a, i32 %b) nounwind { -; RV32I-LABEL: pack_i32: -; RV32I: # %bb.0: -; RV32I-NEXT: lui a2, 16 -; RV32I-NEXT: addi a2, a2, -1 -; RV32I-NEXT: and a0, a0, a2 -; RV32I-NEXT: slli a1, a1, 16 -; RV32I-NEXT: or a0, a1, a0 -; RV32I-NEXT: ret -; -; RV32IB-LABEL: pack_i32: -; RV32IB: # %bb.0: -; RV32IB-NEXT: pack a0, a0, a1 -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: pack_i32: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: pack a0, a0, a1 -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: pack_i32: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: pack a0, a0, a1 -; RV32IBP-NEXT: ret - %shl = and i32 %a, 65535 - %shl1 = shl i32 %b, 16 - %or = or i32 %shl1, %shl - ret i32 %or -} - -; As we are not matching directly i64 code patterns on RV32 some i64 patterns -; don't have yet any matching bit manipulation instructions on RV32. -; This test is presented here in case future expansions of the experimental-b -; extension introduce instructions suitable for this pattern. - -define i64 @pack_i64(i64 %a, i64 %b) nounwind { -; RV32I-LABEL: pack_i64: -; RV32I: # %bb.0: -; RV32I-NEXT: mv a1, a2 -; RV32I-NEXT: ret -; -; RV32IB-LABEL: pack_i64: -; RV32IB: # %bb.0: -; RV32IB-NEXT: mv a1, a2 -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: pack_i64: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: mv a1, a2 -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: pack_i64: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: mv a1, a2 -; RV32IBP-NEXT: ret - %shl = and i64 %a, 4294967295 - %shl1 = shl i64 %b, 32 - %or = or i64 %shl1, %shl - ret i64 %or -} - -define i32 @packu_i32(i32 %a, i32 %b) nounwind { -; RV32I-LABEL: packu_i32: -; RV32I: # %bb.0: -; RV32I-NEXT: srli a0, a0, 16 -; RV32I-NEXT: lui a2, 1048560 -; RV32I-NEXT: and a1, a1, a2 -; RV32I-NEXT: or a0, a1, a0 -; RV32I-NEXT: ret -; -; RV32IB-LABEL: packu_i32: -; RV32IB: # %bb.0: -; RV32IB-NEXT: packu a0, a0, a1 -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: packu_i32: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: packu a0, a0, a1 -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: packu_i32: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: packu a0, a0, a1 -; RV32IBP-NEXT: ret - %shr = lshr i32 %a, 16 - %shr1 = and i32 %b, -65536 - %or = or i32 %shr1, %shr - ret i32 %or -} - -; As we are not matching directly i64 code patterns on RV32 some i64 patterns -; don't have yet any matching bit manipulation instructions on RV32. -; This test is presented here in case future expansions of the experimental-b -; extension introduce instructions suitable for this pattern. - -define i64 @packu_i64(i64 %a, i64 %b) nounwind { -; RV32I-LABEL: packu_i64: -; RV32I: # %bb.0: -; RV32I-NEXT: mv a0, a1 -; RV32I-NEXT: mv a1, a3 -; RV32I-NEXT: ret -; -; RV32IB-LABEL: packu_i64: -; RV32IB: # %bb.0: -; RV32IB-NEXT: mv a0, a1 -; RV32IB-NEXT: mv a1, a3 -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: packu_i64: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: mv a0, a1 -; RV32IBB-NEXT: mv a1, a3 -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: packu_i64: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: mv a0, a1 -; RV32IBP-NEXT: mv a1, a3 -; RV32IBP-NEXT: ret - %shr = lshr i64 %a, 32 - %shr1 = and i64 %b, -4294967296 - %or = or i64 %shr1, %shr - ret i64 %or -} - -define i32 @packh_i32(i32 %a, i32 %b) nounwind { -; RV32I-LABEL: packh_i32: -; RV32I: # %bb.0: -; RV32I-NEXT: andi a0, a0, 255 -; RV32I-NEXT: slli a1, a1, 8 -; RV32I-NEXT: lui a2, 16 -; RV32I-NEXT: addi a2, a2, -256 -; RV32I-NEXT: and a1, a1, a2 -; RV32I-NEXT: or a0, a1, a0 -; RV32I-NEXT: ret -; -; RV32IB-LABEL: packh_i32: -; RV32IB: # %bb.0: -; RV32IB-NEXT: packh a0, a0, a1 -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: packh_i32: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: packh a0, a0, a1 -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: packh_i32: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: packh a0, a0, a1 -; RV32IBP-NEXT: ret - %and = and i32 %a, 255 - %and1 = shl i32 %b, 8 - %shl = and i32 %and1, 65280 - %or = or i32 %shl, %and - ret i32 %or -} - -define i64 @packh_i64(i64 %a, i64 %b) nounwind { -; RV32I-LABEL: packh_i64: -; RV32I: # %bb.0: -; RV32I-NEXT: andi a0, a0, 255 -; RV32I-NEXT: slli a1, a2, 8 -; RV32I-NEXT: lui a2, 16 -; RV32I-NEXT: addi a2, a2, -256 -; RV32I-NEXT: and a1, a1, a2 -; RV32I-NEXT: or a0, a1, a0 -; RV32I-NEXT: mv a1, zero -; RV32I-NEXT: ret -; -; RV32IB-LABEL: packh_i64: -; RV32IB: # %bb.0: -; RV32IB-NEXT: packh a0, a0, a2 -; RV32IB-NEXT: mv a1, zero -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: packh_i64: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: packh a0, a0, a2 -; RV32IBB-NEXT: mv a1, zero -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: packh_i64: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: packh a0, a0, a2 -; RV32IBP-NEXT: mv a1, zero -; RV32IBP-NEXT: ret - %and = and i64 %a, 255 - %and1 = shl i64 %b, 8 - %shl = and i64 %and1, 65280 - %or = or i64 %shl, %and - ret i64 %or -} - -define i32 @zexth_i32(i32 %a) nounwind { -; RV32I-LABEL: zexth_i32: -; RV32I: # %bb.0: -; RV32I-NEXT: lui a1, 16 -; RV32I-NEXT: addi a1, a1, -1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: ret -; -; RV32IB-LABEL: zexth_i32: -; RV32IB: # %bb.0: -; RV32IB-NEXT: zext.h a0, a0 -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: zexth_i32: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: zext.h a0, a0 -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: zexth_i32: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: pack a0, a0, zero -; RV32IBP-NEXT: ret - %and = and i32 %a, 65535 - ret i32 %and -} - -define i64 @zexth_i64(i64 %a) nounwind { -; RV32I-LABEL: zexth_i64: -; RV32I: # %bb.0: -; RV32I-NEXT: lui a1, 16 -; RV32I-NEXT: addi a1, a1, -1 -; RV32I-NEXT: and a0, a0, a1 -; RV32I-NEXT: mv a1, zero -; RV32I-NEXT: ret -; -; RV32IB-LABEL: zexth_i64: -; RV32IB: # %bb.0: -; RV32IB-NEXT: zext.h a0, a0 -; RV32IB-NEXT: mv a1, zero -; RV32IB-NEXT: ret -; -; RV32IBB-LABEL: zexth_i64: -; RV32IBB: # %bb.0: -; RV32IBB-NEXT: zext.h a0, a0 -; RV32IBB-NEXT: mv a1, zero -; RV32IBB-NEXT: ret -; -; RV32IBP-LABEL: zexth_i64: -; RV32IBP: # %bb.0: -; RV32IBP-NEXT: pack a0, a0, zero -; RV32IBP-NEXT: mv a1, zero -; RV32IBP-NEXT: ret - %and = and i64 %a, 65535 - ret i64 %and -} 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 @@ -3431,3 +3431,209 @@ %or3 = or i64 %or, %and2 ret i64 %or3 } + +define i32 @pack_i32(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: pack_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a2, 16 +; RV32I-NEXT: addi a2, a2, -1 +; RV32I-NEXT: and a0, a0, a2 +; RV32I-NEXT: slli a1, a1, 16 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: pack_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT: pack a0, a0, a1 +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: pack_i32: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: pack a0, a0, a1 +; RV32IBP-NEXT: ret + %shl = and i32 %a, 65535 + %shl1 = shl i32 %b, 16 + %or = or i32 %shl1, %shl + ret i32 %or +} + +; As we are not matching directly i64 code patterns on RV32 some i64 patterns +; don't have yet any matching bit manipulation instructions on RV32. +; This test is presented here in case future expansions of the experimental-b +; extension introduce instructions suitable for this pattern. + +define i64 @pack_i64(i64 %a, i64 %b) nounwind { +; RV32I-LABEL: pack_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: mv a1, a2 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: pack_i64: +; RV32IB: # %bb.0: +; RV32IB-NEXT: mv a1, a2 +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: pack_i64: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: mv a1, a2 +; RV32IBP-NEXT: ret + %shl = and i64 %a, 4294967295 + %shl1 = shl i64 %b, 32 + %or = or i64 %shl1, %shl + ret i64 %or +} + +define i32 @packu_i32(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: packu_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: srli a0, a0, 16 +; RV32I-NEXT: lui a2, 1048560 +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: packu_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT: packu a0, a0, a1 +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: packu_i32: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: packu a0, a0, a1 +; RV32IBP-NEXT: ret + %shr = lshr i32 %a, 16 + %shr1 = and i32 %b, -65536 + %or = or i32 %shr1, %shr + ret i32 %or +} + +; As we are not matching directly i64 code patterns on RV32 some i64 patterns +; don't have yet any matching bit manipulation instructions on RV32. +; This test is presented here in case future expansions of the experimental-b +; extension introduce instructions suitable for this pattern. + +define i64 @packu_i64(i64 %a, i64 %b) nounwind { +; RV32I-LABEL: packu_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: mv a0, a1 +; RV32I-NEXT: mv a1, a3 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: packu_i64: +; RV32IB: # %bb.0: +; RV32IB-NEXT: mv a0, a1 +; RV32IB-NEXT: mv a1, a3 +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: packu_i64: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: mv a0, a1 +; RV32IBP-NEXT: mv a1, a3 +; RV32IBP-NEXT: ret + %shr = lshr i64 %a, 32 + %shr1 = and i64 %b, -4294967296 + %or = or i64 %shr1, %shr + ret i64 %or +} + +define i32 @packh_i32(i32 %a, i32 %b) nounwind { +; RV32I-LABEL: packh_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: slli a1, a1, 8 +; RV32I-NEXT: lui a2, 16 +; RV32I-NEXT: addi a2, a2, -256 +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: packh_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT: packh a0, a0, a1 +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: packh_i32: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: packh a0, a0, a1 +; RV32IBP-NEXT: ret + %and = and i32 %a, 255 + %and1 = shl i32 %b, 8 + %shl = and i32 %and1, 65280 + %or = or i32 %shl, %and + ret i32 %or +} + +define i64 @packh_i64(i64 %a, i64 %b) nounwind { +; RV32I-LABEL: packh_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: andi a0, a0, 255 +; RV32I-NEXT: slli a1, a2, 8 +; RV32I-NEXT: lui a2, 16 +; RV32I-NEXT: addi a2, a2, -256 +; RV32I-NEXT: and a1, a1, a2 +; RV32I-NEXT: or a0, a1, a0 +; RV32I-NEXT: mv a1, zero +; RV32I-NEXT: ret +; +; RV32IB-LABEL: packh_i64: +; RV32IB: # %bb.0: +; RV32IB-NEXT: packh a0, a0, a2 +; RV32IB-NEXT: mv a1, zero +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: packh_i64: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: packh a0, a0, a2 +; RV32IBP-NEXT: mv a1, zero +; RV32IBP-NEXT: ret + %and = and i64 %a, 255 + %and1 = shl i64 %b, 8 + %shl = and i64 %and1, 65280 + %or = or i64 %shl, %and + ret i64 %or +} + +define i32 @zexth_i32(i32 %a) nounwind { +; RV32I-LABEL: zexth_i32: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 16 +; RV32I-NEXT: addi a1, a1, -1 +; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: ret +; +; RV32IB-LABEL: zexth_i32: +; RV32IB: # %bb.0: +; RV32IB-NEXT: zext.h a0, a0 +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: zexth_i32: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: zext.h a0, a0 +; RV32IBP-NEXT: ret + %and = and i32 %a, 65535 + ret i32 %and +} + +define i64 @zexth_i64(i64 %a) nounwind { +; RV32I-LABEL: zexth_i64: +; RV32I: # %bb.0: +; RV32I-NEXT: lui a1, 16 +; RV32I-NEXT: addi a1, a1, -1 +; RV32I-NEXT: and a0, a0, a1 +; RV32I-NEXT: mv a1, zero +; RV32I-NEXT: ret +; +; RV32IB-LABEL: zexth_i64: +; RV32IB: # %bb.0: +; RV32IB-NEXT: zext.h a0, a0 +; RV32IB-NEXT: mv a1, zero +; RV32IB-NEXT: ret +; +; RV32IBP-LABEL: zexth_i64: +; RV32IBP: # %bb.0: +; RV32IBP-NEXT: zext.h a0, a0 +; RV32IBP-NEXT: mv a1, zero +; RV32IBP-NEXT: ret + %and = and i64 %a, 65535 + ret i64 %and +} diff --git a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll --- a/llvm/test/CodeGen/RISCV/rv64Zbbp.ll +++ b/llvm/test/CodeGen/RISCV/rv64Zbbp.ll @@ -609,186 +609,3 @@ %1 = tail call i64 @llvm.fshr.i64(i64 %a, i64 %a, i64 63) ret i64 %1 } - -define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind { -; RV64I-LABEL: pack_i32: -; RV64I: # %bb.0: -; RV64I-NEXT: lui a2, 16 -; RV64I-NEXT: addiw a2, a2, -1 -; RV64I-NEXT: and a0, a0, a2 -; RV64I-NEXT: slli a1, a1, 16 -; RV64I-NEXT: or a0, a1, a0 -; RV64I-NEXT: sext.w a0, a0 -; RV64I-NEXT: ret -; -; RV64IB-LABEL: pack_i32: -; RV64IB: # %bb.0: -; RV64IB-NEXT: packw a0, a0, a1 -; RV64IB-NEXT: ret -; -; RV64IBB-LABEL: pack_i32: -; RV64IBB: # %bb.0: -; RV64IBB-NEXT: packw a0, a0, a1 -; RV64IBB-NEXT: ret -; -; RV64IBP-LABEL: pack_i32: -; RV64IBP: # %bb.0: -; RV64IBP-NEXT: packw a0, a0, a1 -; RV64IBP-NEXT: ret - %shl = and i32 %a, 65535 - %shl1 = shl i32 %b, 16 - %or = or i32 %shl1, %shl - ret i32 %or -} - -define i64 @pack_i64(i64 %a, i64 %b) nounwind { -; RV64I-LABEL: pack_i64: -; RV64I: # %bb.0: -; RV64I-NEXT: slli a0, a0, 32 -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: slli a1, a1, 32 -; RV64I-NEXT: or a0, a1, a0 -; RV64I-NEXT: ret -; -; RV64IB-LABEL: pack_i64: -; RV64IB: # %bb.0: -; RV64IB-NEXT: pack a0, a0, a1 -; RV64IB-NEXT: ret -; -; RV64IBB-LABEL: pack_i64: -; RV64IBB: # %bb.0: -; RV64IBB-NEXT: pack a0, a0, a1 -; RV64IBB-NEXT: ret -; -; RV64IBP-LABEL: pack_i64: -; RV64IBP: # %bb.0: -; RV64IBP-NEXT: pack a0, a0, a1 -; RV64IBP-NEXT: ret - %shl = and i64 %a, 4294967295 - %shl1 = shl i64 %b, 32 - %or = or i64 %shl1, %shl - ret i64 %or -} - -define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind { -; RV64I-LABEL: packu_i32: -; RV64I: # %bb.0: -; RV64I-NEXT: srliw a0, a0, 16 -; RV64I-NEXT: lui a2, 1048560 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: or a0, a1, a0 -; RV64I-NEXT: ret -; -; RV64IB-LABEL: packu_i32: -; RV64IB: # %bb.0: -; RV64IB-NEXT: packuw a0, a0, a1 -; RV64IB-NEXT: ret -; -; RV64IBB-LABEL: packu_i32: -; RV64IBB: # %bb.0: -; RV64IBB-NEXT: packuw a0, a0, a1 -; RV64IBB-NEXT: ret -; -; RV64IBP-LABEL: packu_i32: -; RV64IBP: # %bb.0: -; RV64IBP-NEXT: packuw a0, a0, a1 -; RV64IBP-NEXT: ret - %shr = lshr i32 %a, 16 - %shr1 = and i32 %b, -65536 - %or = or i32 %shr1, %shr - ret i32 %or -} - -define i64 @packu_i64(i64 %a, i64 %b) nounwind { -; RV64I-LABEL: packu_i64: -; RV64I: # %bb.0: -; RV64I-NEXT: srli a0, a0, 32 -; RV64I-NEXT: addi a2, zero, -1 -; RV64I-NEXT: slli a2, a2, 32 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: or a0, a1, a0 -; RV64I-NEXT: ret -; -; RV64IB-LABEL: packu_i64: -; RV64IB: # %bb.0: -; RV64IB-NEXT: packu a0, a0, a1 -; RV64IB-NEXT: ret -; -; RV64IBB-LABEL: packu_i64: -; RV64IBB: # %bb.0: -; RV64IBB-NEXT: packu a0, a0, a1 -; RV64IBB-NEXT: ret -; -; RV64IBP-LABEL: packu_i64: -; RV64IBP: # %bb.0: -; RV64IBP-NEXT: packu a0, a0, a1 -; RV64IBP-NEXT: ret - %shr = lshr i64 %a, 32 - %shr1 = and i64 %b, -4294967296 - %or = or i64 %shr1, %shr - ret i64 %or -} - -define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind { -; RV64I-LABEL: packh_i32: -; RV64I: # %bb.0: -; RV64I-NEXT: andi a0, a0, 255 -; RV64I-NEXT: slli a1, a1, 8 -; RV64I-NEXT: lui a2, 16 -; RV64I-NEXT: addiw a2, a2, -256 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: or a0, a1, a0 -; RV64I-NEXT: ret -; -; RV64IB-LABEL: packh_i32: -; RV64IB: # %bb.0: -; RV64IB-NEXT: packh a0, a0, a1 -; RV64IB-NEXT: ret -; -; RV64IBB-LABEL: packh_i32: -; RV64IBB: # %bb.0: -; RV64IBB-NEXT: packh a0, a0, a1 -; RV64IBB-NEXT: ret -; -; RV64IBP-LABEL: packh_i32: -; RV64IBP: # %bb.0: -; RV64IBP-NEXT: packh a0, a0, a1 -; RV64IBP-NEXT: ret - %and = and i32 %a, 255 - %and1 = shl i32 %b, 8 - %shl = and i32 %and1, 65280 - %or = or i32 %shl, %and - ret i32 %or -} - -define i64 @packh_i64(i64 %a, i64 %b) nounwind { -; RV64I-LABEL: packh_i64: -; RV64I: # %bb.0: -; RV64I-NEXT: andi a0, a0, 255 -; RV64I-NEXT: slli a1, a1, 8 -; RV64I-NEXT: lui a2, 16 -; RV64I-NEXT: addiw a2, a2, -256 -; RV64I-NEXT: and a1, a1, a2 -; RV64I-NEXT: or a0, a1, a0 -; RV64I-NEXT: ret -; -; RV64IB-LABEL: packh_i64: -; RV64IB: # %bb.0: -; RV64IB-NEXT: packh a0, a0, a1 -; RV64IB-NEXT: ret -; -; RV64IBB-LABEL: packh_i64: -; RV64IBB: # %bb.0: -; RV64IBB-NEXT: packh a0, a0, a1 -; RV64IBB-NEXT: ret -; -; RV64IBP-LABEL: packh_i64: -; RV64IBP: # %bb.0: -; RV64IBP-NEXT: packh a0, a0, a1 -; RV64IBP-NEXT: ret - %and = and i64 %a, 255 - %and1 = shl i64 %b, 8 - %shl = and i64 %and1, 65280 - %or = or i64 %shl, %and - ret i64 %or -} 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 @@ -3921,3 +3921,198 @@ %or3 = or i64 %or, %and2 ret i64 %or3 } + +define signext i32 @pack_i32(i32 signext %a, i32 signext %b) nounwind { +; RV64I-LABEL: pack_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a2, 16 +; RV64I-NEXT: addiw a2, a2, -1 +; RV64I-NEXT: and a0, a0, a2 +; RV64I-NEXT: slli a1, a1, 16 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: sext.w a0, a0 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: pack_i32: +; RV64IB: # %bb.0: +; RV64IB-NEXT: packw a0, a0, a1 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: pack_i32: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: packw a0, a0, a1 +; RV64IBP-NEXT: ret + %shl = and i32 %a, 65535 + %shl1 = shl i32 %b, 16 + %or = or i32 %shl1, %shl + ret i32 %or +} + +define i64 @pack_i64(i64 %a, i64 %b) nounwind { +; RV64I-LABEL: pack_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: slli a0, a0, 32 +; RV64I-NEXT: srli a0, a0, 32 +; RV64I-NEXT: slli a1, a1, 32 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: pack_i64: +; RV64IB: # %bb.0: +; RV64IB-NEXT: pack a0, a0, a1 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: pack_i64: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: pack a0, a0, a1 +; RV64IBP-NEXT: ret + %shl = and i64 %a, 4294967295 + %shl1 = shl i64 %b, 32 + %or = or i64 %shl1, %shl + ret i64 %or +} + +define signext i32 @packu_i32(i32 signext %a, i32 signext %b) nounwind { +; RV64I-LABEL: packu_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: srliw a0, a0, 16 +; RV64I-NEXT: lui a2, 1048560 +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: packu_i32: +; RV64IB: # %bb.0: +; RV64IB-NEXT: packuw a0, a0, a1 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: packu_i32: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: packuw a0, a0, a1 +; RV64IBP-NEXT: ret + %shr = lshr i32 %a, 16 + %shr1 = and i32 %b, -65536 + %or = or i32 %shr1, %shr + ret i32 %or +} + +define i64 @packu_i64(i64 %a, i64 %b) nounwind { +; RV64I-LABEL: packu_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: srli a0, a0, 32 +; RV64I-NEXT: addi a2, zero, -1 +; RV64I-NEXT: slli a2, a2, 32 +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: packu_i64: +; RV64IB: # %bb.0: +; RV64IB-NEXT: packu a0, a0, a1 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: packu_i64: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: packu a0, a0, a1 +; RV64IBP-NEXT: ret + %shr = lshr i64 %a, 32 + %shr1 = and i64 %b, -4294967296 + %or = or i64 %shr1, %shr + ret i64 %or +} + +define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind { +; RV64I-LABEL: packh_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: andi a0, a0, 255 +; RV64I-NEXT: slli a1, a1, 8 +; RV64I-NEXT: lui a2, 16 +; RV64I-NEXT: addiw a2, a2, -256 +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: packh_i32: +; RV64IB: # %bb.0: +; RV64IB-NEXT: packh a0, a0, a1 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: packh_i32: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: packh a0, a0, a1 +; RV64IBP-NEXT: ret + %and = and i32 %a, 255 + %and1 = shl i32 %b, 8 + %shl = and i32 %and1, 65280 + %or = or i32 %shl, %and + ret i32 %or +} + +define i64 @packh_i64(i64 %a, i64 %b) nounwind { +; RV64I-LABEL: packh_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: andi a0, a0, 255 +; RV64I-NEXT: slli a1, a1, 8 +; RV64I-NEXT: lui a2, 16 +; RV64I-NEXT: addiw a2, a2, -256 +; RV64I-NEXT: and a1, a1, a2 +; RV64I-NEXT: or a0, a1, a0 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: packh_i64: +; RV64IB: # %bb.0: +; RV64IB-NEXT: packh a0, a0, a1 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: packh_i64: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: packh a0, a0, a1 +; RV64IBP-NEXT: ret + %and = and i64 %a, 255 + %and1 = shl i64 %b, 8 + %shl = and i64 %and1, 65280 + %or = or i64 %shl, %and + ret i64 %or +} + +define i32 @zexth_i32(i32 %a) nounwind { +; RV64I-LABEL: zexth_i32: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a1, 16 +; RV64I-NEXT: addiw a1, a1, -1 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: zexth_i32: +; RV64IB: # %bb.0: +; RV64IB-NEXT: zext.h a0, a0 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: zexth_i32: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: zext.h a0, a0 +; RV64IBP-NEXT: ret + %and = and i32 %a, 65535 + ret i32 %and +} + +define i64 @zexth_i64(i64 %a) nounwind { +; RV64I-LABEL: zexth_i64: +; RV64I: # %bb.0: +; RV64I-NEXT: lui a1, 16 +; RV64I-NEXT: addiw a1, a1, -1 +; RV64I-NEXT: and a0, a0, a1 +; RV64I-NEXT: ret +; +; RV64IB-LABEL: zexth_i64: +; RV64IB: # %bb.0: +; RV64IB-NEXT: zext.h a0, a0 +; RV64IB-NEXT: ret +; +; RV64IBP-LABEL: zexth_i64: +; RV64IBP: # %bb.0: +; RV64IBP-NEXT: zext.h a0, a0 +; RV64IBP-NEXT: ret + %and = and i64 %a, 65535 + ret i64 %and +} diff --git a/llvm/test/MC/RISCV/rv32zbbp-invalid.s b/llvm/test/MC/RISCV/rv32zbbp-invalid.s --- a/llvm/test/MC/RISCV/rv32zbbp-invalid.s +++ b/llvm/test/MC/RISCV/rv32zbbp-invalid.s @@ -15,9 +15,3 @@ # Immediate operand out of range rori t0, t1, 32 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31] rori t0, t1, -1 # CHECK: :[[@LINE]]:14: error: immediate must be an integer in the range [0, 31] -# Too few operands -pack t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction -# Too few operands -packu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction -# Too few operands -packh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction diff --git a/llvm/test/MC/RISCV/rv32zbbp-valid.s b/llvm/test/MC/RISCV/rv32zbbp-valid.s --- a/llvm/test/MC/RISCV/rv32zbbp-valid.s +++ b/llvm/test/MC/RISCV/rv32zbbp-valid.s @@ -40,12 +40,3 @@ # CHECK-ASM-AND-OBJ: rori t0, t1, 0 # CHECK-ASM: encoding: [0x93,0x52,0x03,0x60] rori t0, t1, 0 -# CHECK-ASM-AND-OBJ: pack t0, t1, t2 -# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08] -pack t0, t1, t2 -# CHECK-ASM-AND-OBJ: packu t0, t1, t2 -# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48] -packu t0, t1, t2 -# CHECK-ASM-AND-OBJ: packh t0, t1, t2 -# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08] -packh t0, t1, t2 diff --git a/llvm/test/MC/RISCV/rv32zbp-invalid.s b/llvm/test/MC/RISCV/rv32zbp-invalid.s --- a/llvm/test/MC/RISCV/rv32zbp-invalid.s +++ b/llvm/test/MC/RISCV/rv32zbp-invalid.s @@ -42,3 +42,9 @@ # Immediate operand out of range unshfli t0, t1, 16 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] unshfli t0, t1, -1 # CHECK: :[[@LINE]]:17: error: immediate must be an integer in the range [0, 15] +# Too few operands +pack t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +# Too few operands +packu t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction +# Too few operands +packh t0, t1 # CHECK: :[[@LINE]]:1: error: too few operands for instruction diff --git a/llvm/test/MC/RISCV/rv32zbp-valid.s b/llvm/test/MC/RISCV/rv32zbp-valid.s --- a/llvm/test/MC/RISCV/rv32zbp-valid.s +++ b/llvm/test/MC/RISCV/rv32zbp-valid.s @@ -48,3 +48,12 @@ # CHECK-ASM-AND-OBJ: unshfli t0, t1, 0 # CHECK-ASM: encoding: [0x93,0x52,0x03,0x08] unshfli t0, t1, 0 +# CHECK-ASM-AND-OBJ: pack t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x08] +pack t0, t1, t2 +# CHECK-ASM-AND-OBJ: packu t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x42,0x73,0x48] +packu t0, t1, t2 +# CHECK-ASM-AND-OBJ: packh t0, t1, t2 +# CHECK-ASM: encoding: [0xb3,0x72,0x73,0x08] +packh t0, t1, t2 diff --git a/llvm/test/MC/RISCV/rv64zbbp-valid.s b/llvm/test/MC/RISCV/rv64zbbp-valid.s --- a/llvm/test/MC/RISCV/rv64zbbp-valid.s +++ b/llvm/test/MC/RISCV/rv64zbbp-valid.s @@ -31,9 +31,3 @@ # CHECK-ASM-AND-OBJ: roriw t0, t1, 0 # CHECK-ASM: encoding: [0x9b,0x52,0x03,0x60] roriw t0, t1, 0 -# CHECK-ASM-AND-OBJ: packw t0, t1, t2 -# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08] -packw t0, t1, t2 -# CHECK-ASM-AND-OBJ: packuw t0, t1, t2 -# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48] -packuw t0, t1, t2 diff --git a/llvm/test/MC/RISCV/rv64zbp-valid.s b/llvm/test/MC/RISCV/rv64zbp-valid.s --- a/llvm/test/MC/RISCV/rv64zbp-valid.s +++ b/llvm/test/MC/RISCV/rv64zbp-valid.s @@ -42,3 +42,9 @@ # CHECK-ASM-AND-OBJ: unshflw t0, t1, t2 # CHECK-ASM: encoding: [0xbb,0x52,0x73,0x08] unshflw t0, t1, t2 +# CHECK-ASM-AND-OBJ: packw t0, t1, t2 +# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x08] +packw t0, t1, t2 +# CHECK-ASM-AND-OBJ: packuw t0, t1, t2 +# CHECK-ASM: encoding: [0xbb,0x42,0x73,0x48] +packuw t0, t1, t2