Skip to content

Commit 13e32a8

Browse files
committed
[RISCV] Improve use of PACK instruction on rv64.
Handle the case where the lower bits come from a zero extending load or other operation with known zero bits.
1 parent d7c1427 commit 13e32a8

File tree

3 files changed

+41
-1
lines changed

3 files changed

+41
-1
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -648,7 +648,7 @@ def : Pat<(i32 (or (zexti16 GPR:$rs1), (shl GPR:$rs2, (i32 16)))),
648648
(PACK GPR:$rs1, GPR:$rs2)>;
649649

650650
let Predicates = [HasStdExtZbkb, IsRV64] in {
651-
def : Pat<(i64 (or (and GPR:$rs1, 0x00000000FFFFFFFF), (shl GPR:$rs2, (i64 32)))),
651+
def : Pat<(i64 (or (zexti32 GPR:$rs1), (shl GPR:$rs2, (i64 32)))),
652652
(PACK GPR:$rs1, GPR:$rs2)>;
653653

654654
def : Pat<(binop_allwusers<or> (shl GPR:$rs2, (i64 16)),

llvm/test/CodeGen/RISCV/rv32zbkb.ll

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,22 @@ define i64 @pack_i64_2(i32 %a, i32 %b) nounwind {
8989
ret i64 %or
9090
}
9191

92+
define i64 @pack_i64_3(ptr %0, ptr %1) {
93+
; CHECK-LABEL: pack_i64_3:
94+
; CHECK: # %bb.0:
95+
; CHECK-NEXT: lw a2, 0(a0)
96+
; CHECK-NEXT: lw a0, 0(a1)
97+
; CHECK-NEXT: mv a1, a2
98+
; CHECK-NEXT: ret
99+
%3 = load i32, ptr %0, align 4
100+
%4 = zext i32 %3 to i64
101+
%5 = shl i64 %4, 32
102+
%6 = load i32, ptr %1, align 4
103+
%7 = zext i32 %6 to i64
104+
%8 = or i64 %5, %7
105+
ret i64 %8
106+
}
107+
92108
; As we are not matching directly i64 code patterns on RV32 some i64 patterns
93109
; don't have yet any matching bit manipulation instructions on RV32.
94110
; This test is presented here in case future expansions of the Bitmanip

llvm/test/CodeGen/RISCV/rv64zbkb.ll

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,30 @@ define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
102102
ret i64 %or
103103
}
104104

105+
define i64 @pack_i64_3(ptr %0, ptr %1) {
106+
; RV64I-LABEL: pack_i64_3:
107+
; RV64I: # %bb.0:
108+
; RV64I-NEXT: lw a0, 0(a0)
109+
; RV64I-NEXT: lwu a1, 0(a1)
110+
; RV64I-NEXT: slli a0, a0, 32
111+
; RV64I-NEXT: or a0, a0, a1
112+
; RV64I-NEXT: ret
113+
;
114+
; RV64ZBKB-LABEL: pack_i64_3:
115+
; RV64ZBKB: # %bb.0:
116+
; RV64ZBKB-NEXT: lw a0, 0(a0)
117+
; RV64ZBKB-NEXT: lwu a1, 0(a1)
118+
; RV64ZBKB-NEXT: pack a0, a1, a0
119+
; RV64ZBKB-NEXT: ret
120+
%3 = load i32, ptr %0, align 4
121+
%4 = zext i32 %3 to i64
122+
%5 = shl i64 %4, 32
123+
%6 = load i32, ptr %1, align 4
124+
%7 = zext i32 %6 to i64
125+
%8 = or i64 %5, %7
126+
ret i64 %8
127+
}
128+
105129
define signext i32 @packh_i32(i32 signext %a, i32 signext %b) nounwind {
106130
; RV64I-LABEL: packh_i32:
107131
; RV64I: # %bb.0:

0 commit comments

Comments
 (0)