Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 31 additions & 1 deletion llvm/include/llvm/Target/GlobalISel/Combine.td
Original file line number Diff line number Diff line change
Expand Up @@ -1040,6 +1040,34 @@ def funnel_shift_overshift: GICombineRule<
(apply [{ Helper.applyFunnelShiftConstantModulo(*${root}); }])
>;

// Transform: fshl x, z, y | shl x, y -> fshl x, z, y
// Transform: shl x, y | fshl x, z, y -> fshl x, z, y
// FIXME: TableGen didn't handle G_OR commutativity on its own,
// necessitating the use of !foreach to handle it manually.
def funnel_shift_or_shift_to_funnel_shift_left_frags : GICombinePatFrag<
(outs root: $dst, $out1, $out2), (ins),
!foreach(inst, [(G_OR $dst, $out1, $out2), (G_OR $dst, $out2, $out1)],
(pattern (G_FSHL $out1, $x, $z, $y), (G_SHL $out2, $x, $y), inst))>;
def funnel_shift_or_shift_to_funnel_shift_left: GICombineRule<
(defs root:$root),
(match (funnel_shift_or_shift_to_funnel_shift_left_frags $root, $out1, $out2)),
(apply (GIReplaceReg $root, $out1))
>;

// Transform: fshr z, x, y | srl x, y -> fshr z, x, y
// Transform: srl x, y | fshr z, x, y -> fshr z, x, y
// FIXME: TableGen didn't handle G_OR commutativity on its own,
// necessitating the use of !foreach to handle it manually.
def funnel_shift_or_shift_to_funnel_shift_right_frags : GICombinePatFrag<
(outs root: $dst, $out1, $out2), (ins),
!foreach(inst, [(G_OR $dst, $out1, $out2), (G_OR $dst, $out2, $out1)],
(pattern (G_FSHR $out1, $z, $x, $y), (G_LSHR $out2, $x, $y), inst))>;
def funnel_shift_or_shift_to_funnel_shift_right: GICombineRule<
(defs root:$root),
(match (funnel_shift_or_shift_to_funnel_shift_right_frags $root, $out1, $out2)),
(apply (GIReplaceReg $root, $out1))
>;

def rotate_out_of_range : GICombineRule<
(defs root:$root),
(match (wip_match_opcode G_ROTR, G_ROTL):$root,
Expand Down Expand Up @@ -1112,7 +1140,9 @@ def funnel_shift_combines : GICombineGroup<[funnel_shift_from_or_shift,
funnel_shift_to_rotate,
funnel_shift_right_zero,
funnel_shift_left_zero,
funnel_shift_overshift]>;
funnel_shift_overshift,
funnel_shift_or_shift_to_funnel_shift_left,
funnel_shift_or_shift_to_funnel_shift_right]>;

def bitfield_extract_from_sext_inreg : GICombineRule<
(defs root:$root, build_fn_matchinfo:$info),
Expand Down
24 changes: 10 additions & 14 deletions llvm/test/CodeGen/AArch64/funnel-shift.ll
Original file line number Diff line number Diff line change
Expand Up @@ -674,14 +674,12 @@ define i32 @or_shl_fshl_simplify(i32 %x, i32 %y, i32 %s) {
; CHECK-GI-LABEL: or_shl_fshl_simplify:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #31 // =0x1f
; CHECK-GI-NEXT: and w9, w2, #0x1f
; CHECK-GI-NEXT: lsr w10, w0, #1
; CHECK-GI-NEXT: lsl w11, w1, w2
; CHECK-GI-NEXT: lsr w9, w0, #1
; CHECK-GI-NEXT: and w10, w2, #0x1f
; CHECK-GI-NEXT: bic w8, w8, w2
; CHECK-GI-NEXT: lsl w9, w1, w9
; CHECK-GI-NEXT: lsr w8, w10, w8
; CHECK-GI-NEXT: orr w9, w9, w11
; CHECK-GI-NEXT: orr w0, w9, w8
; CHECK-GI-NEXT: lsl w10, w1, w10
; CHECK-GI-NEXT: lsr w8, w9, w8
; CHECK-GI-NEXT: orr w0, w10, w8
; CHECK-GI-NEXT: ret
%shy = shl i32 %y, %s
%fun = call i32 @llvm.fshl.i32(i32 %y, i32 %x, i32 %s)
Expand All @@ -702,14 +700,12 @@ define i32 @or_lshr_fshr_simplify(i32 %x, i32 %y, i32 %s) {
; CHECK-GI-LABEL: or_lshr_fshr_simplify:
; CHECK-GI: // %bb.0:
; CHECK-GI-NEXT: mov w8, #31 // =0x1f
; CHECK-GI-NEXT: and w9, w2, #0x1f
; CHECK-GI-NEXT: lsl w10, w0, #1
; CHECK-GI-NEXT: lsr w11, w1, w2
; CHECK-GI-NEXT: lsl w9, w0, #1
; CHECK-GI-NEXT: and w10, w2, #0x1f
; CHECK-GI-NEXT: bic w8, w8, w2
; CHECK-GI-NEXT: lsr w9, w1, w9
; CHECK-GI-NEXT: lsl w8, w10, w8
; CHECK-GI-NEXT: orr w9, w11, w9
; CHECK-GI-NEXT: orr w0, w9, w8
; CHECK-GI-NEXT: lsl w8, w9, w8
; CHECK-GI-NEXT: lsr w9, w1, w10
; CHECK-GI-NEXT: orr w0, w8, w9
; CHECK-GI-NEXT: ret
%shy = lshr i32 %y, %s
%fun = call i32 @llvm.fshr.i32(i32 %x, i32 %y, i32 %s)
Expand Down
48 changes: 48 additions & 0 deletions llvm/test/CodeGen/RISCV/GlobalISel/shift.ll
Original file line number Diff line number Diff line change
Expand Up @@ -105,3 +105,51 @@ define i16 @test_shl_i48_2(i48 %x, i48 %y) {
%trunc = trunc i48 %shl to i16
ret i16 %trunc
}

define i32 @test_fshl_i32(i32 %x, i32 %_, i32 %y) {
; RV32-LABEL: test_fshl_i32:
; RV32: # %bb.0:
; RV32-NEXT: not a3, a2
; RV32-NEXT: sll a0, a0, a2
; RV32-NEXT: srli a1, a1, 1
; RV32-NEXT: srl a1, a1, a3
; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; RV64-LABEL: test_fshl_i32:
; RV64: # %bb.0:
; RV64-NEXT: not a3, a2
; RV64-NEXT: sllw a0, a0, a2
; RV64-NEXT: srliw a1, a1, 1
; RV64-NEXT: srlw a1, a1, a3
; RV64-NEXT: or a0, a0, a1
; RV64-NEXT: ret
%fshl = call i32 @llvm.fshl.i32(i32 %x, i32 %_, i32 %y)
%shl = shl i32 %x, %y
%or = or i32 %fshl, %shl
ret i32 %or
}

define i32 @test_fshr_i32(i32 %_, i32 %x, i32 %y) {
; RV32-LABEL: test_fshr_i32:
; RV32: # %bb.0:
; RV32-NEXT: not a3, a2
; RV32-NEXT: slli a0, a0, 1
; RV32-NEXT: sll a0, a0, a3
; RV32-NEXT: srl a1, a1, a2
; RV32-NEXT: or a0, a0, a1
; RV32-NEXT: ret
;
; RV64-LABEL: test_fshr_i32:
; RV64: # %bb.0:
; RV64-NEXT: not a3, a2
; RV64-NEXT: slli a0, a0, 1
; RV64-NEXT: sllw a0, a0, a3
; RV64-NEXT: srlw a1, a1, a2
; RV64-NEXT: or a0, a0, a1
; RV64-NEXT: ret
%fshr = call i32 @llvm.fshr.i32(i32 %_, i32 %x, i32 %y)
%lshr = lshr i32 %x, %y
%or = or i32 %lshr, %fshr
ret i32 %or
}