Skip to content

Commit fdc904e

Browse files
committed
[RISCV] Add isel pattern to turn (or (zext X), Y) into add.uw when X and Y are disjoint.
Improve code for -riscv-experimental-rv64-legal-i32.
1 parent 12c6625 commit fdc904e

File tree

2 files changed

+71
-0
lines changed

2 files changed

+71
-0
lines changed

llvm/lib/Target/RISCV/RISCVInstrInfoZb.td

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -854,6 +854,9 @@ def : Pat<(i64 (add_non_imm12 (zext GPR:$rs1), GPR:$rs2)),
854854
(ADD_UW GPR:$rs1, GPR:$rs2)>;
855855
def : Pat<(zext GPR:$src), (ADD_UW GPR:$src, (XLenVT X0))>;
856856

857+
def : Pat<(i64 (or_is_add_non_imm12 (zext GPR:$rs1), GPR:$rs2)),
858+
(ADD_UW GPR:$rs1, GPR:$rs2)>;
859+
857860
foreach i = {1,2,3} in {
858861
defvar shxadd = !cast<Instruction>("SH"#i#"ADD");
859862
def : Pat<(i32 (add_non_imm12 (shl GPR:$rs1, (i64 i)), GPR:$rs2)),

llvm/test/CodeGen/RISCV/rv64-legal-i32/rv64zba.ll

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1829,3 +1829,71 @@ define i64 @shl_31_sh3add(ptr %0, i32 signext %1) {
18291829
%6 = load i64, ptr %5, align 8
18301830
ret i64 %6
18311831
}
1832+
1833+
define i64 @pack_i64(i64 %a, i64 %b) nounwind {
1834+
; RV64I-LABEL: pack_i64:
1835+
; RV64I: # %bb.0:
1836+
; RV64I-NEXT: slli a0, a0, 32
1837+
; RV64I-NEXT: srli a0, a0, 32
1838+
; RV64I-NEXT: slli a1, a1, 32
1839+
; RV64I-NEXT: or a0, a1, a0
1840+
; RV64I-NEXT: ret
1841+
;
1842+
; RV64ZBA-LABEL: pack_i64:
1843+
; RV64ZBA: # %bb.0:
1844+
; RV64ZBA-NEXT: slli a1, a1, 32
1845+
; RV64ZBA-NEXT: add.uw a0, a0, a1
1846+
; RV64ZBA-NEXT: ret
1847+
%shl = and i64 %a, 4294967295
1848+
%shl1 = shl i64 %b, 32
1849+
%or = or i64 %shl1, %shl
1850+
ret i64 %or
1851+
}
1852+
1853+
define i64 @pack_i64_2(i32 signext %a, i32 signext %b) nounwind {
1854+
; RV64I-LABEL: pack_i64_2:
1855+
; RV64I: # %bb.0:
1856+
; RV64I-NEXT: slli a0, a0, 32
1857+
; RV64I-NEXT: srli a0, a0, 32
1858+
; RV64I-NEXT: slli a1, a1, 32
1859+
; RV64I-NEXT: or a0, a1, a0
1860+
; RV64I-NEXT: ret
1861+
;
1862+
; RV64ZBA-LABEL: pack_i64_2:
1863+
; RV64ZBA: # %bb.0:
1864+
; RV64ZBA-NEXT: slli a1, a1, 32
1865+
; RV64ZBA-NEXT: add.uw a0, a0, a1
1866+
; RV64ZBA-NEXT: ret
1867+
%zexta = zext i32 %a to i64
1868+
%zextb = zext i32 %b to i64
1869+
%shl1 = shl i64 %zextb, 32
1870+
%or = or i64 %shl1, %zexta
1871+
ret i64 %or
1872+
}
1873+
1874+
define i64 @pack_i64_3(i32 signext %a, i32 signext %b) nounwind {
1875+
; RV64I-LABEL: pack_i64_3:
1876+
; RV64I: # %bb.0:
1877+
; RV64I-NEXT: addi a0, a0, 1
1878+
; RV64I-NEXT: addi a1, a1, 1
1879+
; RV64I-NEXT: slli a0, a0, 32
1880+
; RV64I-NEXT: srli a0, a0, 32
1881+
; RV64I-NEXT: slli a1, a1, 32
1882+
; RV64I-NEXT: or a0, a1, a0
1883+
; RV64I-NEXT: ret
1884+
;
1885+
; RV64ZBA-LABEL: pack_i64_3:
1886+
; RV64ZBA: # %bb.0:
1887+
; RV64ZBA-NEXT: addi a0, a0, 1
1888+
; RV64ZBA-NEXT: addi a1, a1, 1
1889+
; RV64ZBA-NEXT: slli a1, a1, 32
1890+
; RV64ZBA-NEXT: add.uw a0, a0, a1
1891+
; RV64ZBA-NEXT: ret
1892+
%adda = add i32 %a, 1
1893+
%addb = add i32 %b, 1
1894+
%zexta = zext i32 %adda to i64
1895+
%zextb = zext i32 %addb to i64
1896+
%shl1 = shl i64 %zextb, 32
1897+
%or = or i64 %shl1, %zexta
1898+
ret i64 %or
1899+
}

0 commit comments

Comments
 (0)