-
Notifications
You must be signed in to change notification settings - Fork 15.5k
[RISCV] Select (and (shl X, 8), 0xff00) -> (packh zero, X) #170654
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Similar transforms with "pack" and "packw" are not useful: (pack zero, X) == (slli X, XLEN/2) (packw zero, X) == (slliw X, 16)
|
@llvm/pr-subscribers-backend-risc-v Author: Piotr Fusik (pfusik) ChangesSimilar transforms with "pack" and "packw" are not useful: Full diff: https://github.com/llvm/llvm-project/pull/170654.diff 4 Files Affected:
diff --git a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
index b92926e63d880..162de7e99ec9e 100644
--- a/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
+++ b/llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp
@@ -1500,8 +1500,17 @@ void RISCVDAGToDAGISel::Select(SDNode *Node) {
if (tryUnsignedBitfieldInsertInZero(Node, DL, VT, X, Msb, Lsb))
return;
- // (srli (slli c2+c3), c3)
if (OneUseOrZExtW && !IsCANDI) {
+ // (packh x0, X)
+ if (Subtarget->hasStdExtZbkb() && C1 == 0xff00 && C2 == 8) {
+ SDNode *PACKH = CurDAG->getMachineNode(
+ RISCV::PACKH, DL, VT,
+ CurDAG->getRegister(RISCV::X0, Subtarget->getXLenVT()),
+ X);
+ ReplaceNode(Node, PACKH);
+ return;
+ }
+ // (srli (slli c2+c3), c3)
SDNode *SLLI = CurDAG->getMachineNode(
RISCV::SLLI, DL, VT, X,
CurDAG->getTargetConstant(C2 + Leading, DL, VT));
diff --git a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
index 5429c2a1a21b0..443173b997a28 100644
--- a/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
+++ b/llvm/lib/Target/RISCV/RISCVInstrInfoZb.td
@@ -652,6 +652,9 @@ def : Pat<(and (or (shl GPR:$rs2, (XLenVT 8)),
def : Pat<(binop_allhusers<or> (shl GPR:$rs2, (XLenVT 8)),
zexti8:$rs1),
(PACKH zexti8:$rs1, GPR:$rs2)>;
+
+def : Pat<(shl (and GPR:$rs2, 0xFF), (XLenVT 8)),
+ (PACKH (XLenVT X0), GPR:$rs2)>;
} // Predicates = [HasStdExtZbkb]
let Predicates = [HasStdExtZbkb, IsRV32] in {
diff --git a/llvm/test/CodeGen/RISCV/rv32zbkb.ll b/llvm/test/CodeGen/RISCV/rv32zbkb.ll
index 42d326e359d9f..a0d5d26143c35 100644
--- a/llvm/test/CodeGen/RISCV/rv32zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv32zbkb.ll
@@ -458,3 +458,88 @@ define i32 @pack_lo_noext_hi_packh_nozeroext(i32 %a, i8 %1, i8 %2) nounwind {
%g = or i32 %f, %a
ret i32 %g
}
+
+define i32 @packh_zero_i32(i32 %a) nounwind {
+; RV32I-LABEL: packh_zero_i32:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 24
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: packh_zero_i32:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: packh a0, zero, a0
+; RV32ZBKB-NEXT: ret
+ %shl = shl i32 %a, 8
+ %and = and i32 %shl, 65280
+ ret i32 %and
+}
+
+define i32 @packh_zero_i32_2(i32 %a) nounwind {
+; RV32I-LABEL: packh_zero_i32_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: zext.b a0, a0
+; RV32I-NEXT: slli a0, a0, 8
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: packh_zero_i32_2:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: packh a0, zero, a0
+; RV32ZBKB-NEXT: ret
+ %and = and i32 %a, 255
+ %shl = shl i32 %and, 8
+ ret i32 %shl
+}
+
+define i64 @packh_zero_i64(i64 %a) nounwind {
+; RV32I-LABEL: packh_zero_i64:
+; RV32I: # %bb.0:
+; RV32I-NEXT: slli a0, a0, 24
+; RV32I-NEXT: srli a0, a0, 16
+; RV32I-NEXT: li a1, 0
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: packh_zero_i64:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: packh a0, zero, a0
+; RV32ZBKB-NEXT: li a1, 0
+; RV32ZBKB-NEXT: ret
+ %shl = shl i64 %a, 8
+ %and = and i64 %shl, 65280
+ ret i64 %and
+}
+
+define i64 @packh_zero_i64_2(i64 %a) nounwind {
+; RV32I-LABEL: packh_zero_i64_2:
+; RV32I: # %bb.0:
+; RV32I-NEXT: zext.b a0, a0
+; RV32I-NEXT: slli a0, a0, 8
+; RV32I-NEXT: li a1, 0
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: packh_zero_i64_2:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: packh a0, zero, a0
+; RV32ZBKB-NEXT: li a1, 0
+; RV32ZBKB-NEXT: ret
+ %and = and i64 %a, 255
+ %shl = shl i64 %and, 8
+ ret i64 %shl
+}
+
+define i32 @packh_zero_i8(i8 %a) nounwind {
+; RV32I-LABEL: packh_zero_i8:
+; RV32I: # %bb.0:
+; RV32I-NEXT: zext.b a0, a0
+; RV32I-NEXT: slli a0, a0, 8
+; RV32I-NEXT: ret
+;
+; RV32ZBKB-LABEL: packh_zero_i8:
+; RV32ZBKB: # %bb.0:
+; RV32ZBKB-NEXT: packh a0, zero, a0
+; RV32ZBKB-NEXT: ret
+ %zext = zext i8 %a to i32
+ %shl = shl i32 %zext, 8
+ %and = and i32 %shl, 65280
+ ret i32 %and
+}
diff --git a/llvm/test/CodeGen/RISCV/rv64zbkb.ll b/llvm/test/CodeGen/RISCV/rv64zbkb.ll
index b2ad8d76ba953..43e4309a858f9 100644
--- a/llvm/test/CodeGen/RISCV/rv64zbkb.ll
+++ b/llvm/test/CodeGen/RISCV/rv64zbkb.ll
@@ -636,3 +636,84 @@ define i64 @pack_i64_lo_noext_hi_packh_nozeroext(i64 %a, i8 %1, i8 %2, ptr %p) n
%g = or i64 %f, %a
ret i64 %g
}
+
+define i32 @packh_zero_i32(i32 %a) nounwind {
+; RV64I-LABEL: packh_zero_i32:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 56
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: packh_zero_i32:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: packh a0, zero, a0
+; RV64ZBKB-NEXT: ret
+ %shl = shl i32 %a, 8
+ %and = and i32 %shl, 65280
+ ret i32 %and
+}
+
+define i32 @packh_zero_i32_2(i32 %a) nounwind {
+; RV64I-LABEL: packh_zero_i32_2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: zext.b a0, a0
+; RV64I-NEXT: slli a0, a0, 8
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: packh_zero_i32_2:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: packh a0, zero, a0
+; RV64ZBKB-NEXT: ret
+ %and = and i32 %a, 255
+ %shl = shl i32 %and, 8
+ ret i32 %shl
+}
+
+define i64 @packh_zero_i64(i64 %a) nounwind {
+; RV64I-LABEL: packh_zero_i64:
+; RV64I: # %bb.0:
+; RV64I-NEXT: slli a0, a0, 56
+; RV64I-NEXT: srli a0, a0, 48
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: packh_zero_i64:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: packh a0, zero, a0
+; RV64ZBKB-NEXT: ret
+ %shl = shl i64 %a, 8
+ %and = and i64 %shl, 65280
+ ret i64 %and
+}
+
+define i64 @packh_zero_i64_2(i64 %a) nounwind {
+; RV64I-LABEL: packh_zero_i64_2:
+; RV64I: # %bb.0:
+; RV64I-NEXT: zext.b a0, a0
+; RV64I-NEXT: slli a0, a0, 8
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: packh_zero_i64_2:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: packh a0, zero, a0
+; RV64ZBKB-NEXT: ret
+ %and = and i64 %a, 255
+ %shl = shl i64 %and, 8
+ ret i64 %shl
+}
+
+define i32 @packh_zero_i8(i8 %a) nounwind {
+; RV64I-LABEL: packh_zero_i8:
+; RV64I: # %bb.0:
+; RV64I-NEXT: zext.b a0, a0
+; RV64I-NEXT: slli a0, a0, 8
+; RV64I-NEXT: ret
+;
+; RV64ZBKB-LABEL: packh_zero_i8:
+; RV64ZBKB: # %bb.0:
+; RV64ZBKB-NEXT: packh a0, zero, a0
+; RV64ZBKB-NEXT: ret
+ %zext = zext i8 %a to i32
+ %shl = shl i32 %zext, 8
+ %and = and i32 %shl, 65280
+ ret i32 %and
+}
|
|
✅ With the latest revision this PR passed the C/C++ code formatter. |
topperc
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM
Similar transforms with "pack" and "packw" are not useful: (pack zero, X) == (slli X, XLEN/2) (packw zero, X) == (slliw X, 16)
Similar transforms with "pack" and "packw" are not useful:
(pack zero, X) == (slli X, XLEN/2)
(packw zero, X) == (slliw X, 16)