Skip to content

[RISCV] Don't commute with shift if it would break sh{1,2,3}add pattern #119527

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

Merged
merged 4 commits into from
Jan 6, 2025
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
9 changes: 9 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18386,6 +18386,15 @@ bool RISCVTargetLowering::isDesirableToCommuteWithShift(

auto *C1 = dyn_cast<ConstantSDNode>(N0->getOperand(1));
auto *C2 = dyn_cast<ConstantSDNode>(N->getOperand(1));

// Bail if we might break a sh{1,2,3}add pattern.
if (Subtarget.hasStdExtZba() && C2->getZExtValue() >= 1 &&
C2->getZExtValue() <= 3 && N->hasOneUse() &&
N->user_begin()->getOpcode() == ISD::ADD &&
!isUsedByLdSt(*N->user_begin(), nullptr) &&
!isa<ConstantSDNode>(N->user_begin()->getOperand(1)))
return false;

if (C1 && C2) {
const APInt &C1Int = C1->getAPIntValue();
APInt ShiftedC1Int = C1Int << C2->getAPIntValue();
Expand Down
324 changes: 245 additions & 79 deletions llvm/test/CodeGen/RISCV/add_sext_shl_constant.ll
Original file line number Diff line number Diff line change
@@ -1,17 +1,28 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefix=RV64 %s
; RUN: llc -mtriple=riscv64 < %s | FileCheck -check-prefixes=RV64,NO-ZBA %s
; RUN: llc -mtriple=riscv64 -mattr=+zba < %s | FileCheck -check-prefixes=RV64,ZBA %s

define void @add_sext_shl_moreOneUse_add(ptr %array1, i32 %a, i32 %b) {
; RV64-LABEL: add_sext_shl_moreOneUse_add:
; RV64: # %bb.0: # %entry
; RV64-NEXT: addi a3, a1, 5
; RV64-NEXT: sext.w a1, a1
; RV64-NEXT: slli a1, a1, 2
; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: sw a2, 20(a0)
; RV64-NEXT: sw a2, 24(a0)
; RV64-NEXT: sw a3, 140(a0)
; RV64-NEXT: ret
; NO-ZBA-LABEL: add_sext_shl_moreOneUse_add:
; NO-ZBA: # %bb.0: # %entry
; NO-ZBA-NEXT: addi a3, a1, 5
; NO-ZBA-NEXT: sext.w a1, a1
; NO-ZBA-NEXT: slli a1, a1, 2
; NO-ZBA-NEXT: add a0, a1, a0
; NO-ZBA-NEXT: sw a2, 20(a0)
; NO-ZBA-NEXT: sw a2, 24(a0)
; NO-ZBA-NEXT: sw a3, 140(a0)
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_sext_shl_moreOneUse_add:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a3, a1, 5
; ZBA-NEXT: sext.w a1, a1
; ZBA-NEXT: sh2add a0, a1, a0
; ZBA-NEXT: sw a2, 20(a0)
; ZBA-NEXT: sw a2, 24(a0)
; ZBA-NEXT: sw a3, 140(a0)
; ZBA-NEXT: ret
entry:
%add = add nsw i32 %a, 5
%idxprom = sext i32 %add to i64
Expand All @@ -29,19 +40,32 @@ entry:
}

define void @add_sext_shl_moreOneUse_addexceedsign12(ptr %array1, i32 %a, i32 %b) {
; RV64-LABEL: add_sext_shl_moreOneUse_addexceedsign12:
; RV64: # %bb.0: # %entry
; RV64-NEXT: addi a3, a1, 2047
; RV64-NEXT: lui a4, 2
; RV64-NEXT: sext.w a1, a1
; RV64-NEXT: addi a3, a3, 1
; RV64-NEXT: slli a1, a1, 2
; RV64-NEXT: add a0, a0, a4
; RV64-NEXT: add a0, a0, a1
; RV64-NEXT: sw a2, 0(a0)
; RV64-NEXT: sw a3, 4(a0)
; RV64-NEXT: sw a2, 120(a0)
; RV64-NEXT: ret
; NO-ZBA-LABEL: add_sext_shl_moreOneUse_addexceedsign12:
; NO-ZBA: # %bb.0: # %entry
; NO-ZBA-NEXT: addi a3, a1, 2047
; NO-ZBA-NEXT: lui a4, 2
; NO-ZBA-NEXT: sext.w a1, a1
; NO-ZBA-NEXT: addi a3, a3, 1
; NO-ZBA-NEXT: slli a1, a1, 2
; NO-ZBA-NEXT: add a0, a0, a4
; NO-ZBA-NEXT: add a0, a0, a1
; NO-ZBA-NEXT: sw a2, 0(a0)
; NO-ZBA-NEXT: sw a3, 4(a0)
; NO-ZBA-NEXT: sw a2, 120(a0)
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_sext_shl_moreOneUse_addexceedsign12:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a3, a1, 2047
; ZBA-NEXT: lui a4, 2
; ZBA-NEXT: sext.w a1, a1
; ZBA-NEXT: addi a3, a3, 1
; ZBA-NEXT: sh2add a0, a1, a0
; ZBA-NEXT: add a0, a0, a4
; ZBA-NEXT: sw a2, 0(a0)
; ZBA-NEXT: sw a3, 4(a0)
; ZBA-NEXT: sw a2, 120(a0)
; ZBA-NEXT: ret
entry:
%add = add nsw i32 %a, 2048
%idxprom = sext i32 %add to i64
Expand All @@ -57,16 +81,26 @@ entry:
}

define void @add_sext_shl_moreOneUse_sext(ptr %array1, i32 %a, i32 %b) {
; RV64-LABEL: add_sext_shl_moreOneUse_sext:
; RV64: # %bb.0: # %entry
; RV64-NEXT: sext.w a1, a1
; RV64-NEXT: addi a3, a1, 5
; RV64-NEXT: slli a1, a1, 2
; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: sw a2, 20(a0)
; RV64-NEXT: sw a2, 24(a0)
; RV64-NEXT: sd a3, 140(a0)
; RV64-NEXT: ret
; NO-ZBA-LABEL: add_sext_shl_moreOneUse_sext:
; NO-ZBA: # %bb.0: # %entry
; NO-ZBA-NEXT: sext.w a1, a1
; NO-ZBA-NEXT: addi a3, a1, 5
; NO-ZBA-NEXT: slli a1, a1, 2
; NO-ZBA-NEXT: add a0, a1, a0
; NO-ZBA-NEXT: sw a2, 20(a0)
; NO-ZBA-NEXT: sw a2, 24(a0)
; NO-ZBA-NEXT: sd a3, 140(a0)
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_sext_shl_moreOneUse_sext:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: sext.w a1, a1
; ZBA-NEXT: addi a3, a1, 5
; ZBA-NEXT: sh2add a0, a1, a0
; ZBA-NEXT: sw a2, 20(a0)
; ZBA-NEXT: sw a2, 24(a0)
; ZBA-NEXT: sd a3, 140(a0)
; ZBA-NEXT: ret
entry:
%add = add nsw i32 %a, 5
%idxprom = sext i32 %add to i64
Expand All @@ -85,20 +119,34 @@ entry:

; test of jumpping, find add's operand has one more use can simplified
define void @add_sext_shl_moreOneUse_add_inSelect(ptr %array1, i32 signext %a, i32 %b, i32 signext %x) {
; RV64-LABEL: add_sext_shl_moreOneUse_add_inSelect:
; RV64: # %bb.0: # %entry
; RV64-NEXT: addi a4, a1, 5
; RV64-NEXT: mv a5, a4
; RV64-NEXT: bgtz a3, .LBB3_2
; RV64-NEXT: # %bb.1: # %entry
; RV64-NEXT: mv a5, a2
; RV64-NEXT: .LBB3_2: # %entry
; RV64-NEXT: slli a1, a1, 2
; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: sw a5, 20(a0)
; RV64-NEXT: sw a5, 24(a0)
; RV64-NEXT: sw a4, 140(a0)
; RV64-NEXT: ret
; NO-ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect:
; NO-ZBA: # %bb.0: # %entry
; NO-ZBA-NEXT: addi a4, a1, 5
; NO-ZBA-NEXT: mv a5, a4
; NO-ZBA-NEXT: bgtz a3, .LBB3_2
; NO-ZBA-NEXT: # %bb.1: # %entry
; NO-ZBA-NEXT: mv a5, a2
; NO-ZBA-NEXT: .LBB3_2: # %entry
; NO-ZBA-NEXT: slli a1, a1, 2
; NO-ZBA-NEXT: add a0, a1, a0
; NO-ZBA-NEXT: sw a5, 20(a0)
; NO-ZBA-NEXT: sw a5, 24(a0)
; NO-ZBA-NEXT: sw a4, 140(a0)
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a4, a1, 5
; ZBA-NEXT: mv a5, a4
; ZBA-NEXT: bgtz a3, .LBB3_2
; ZBA-NEXT: # %bb.1: # %entry
; ZBA-NEXT: mv a5, a2
; ZBA-NEXT: .LBB3_2: # %entry
; ZBA-NEXT: sh2add a0, a1, a0
; ZBA-NEXT: sw a5, 20(a0)
; ZBA-NEXT: sw a5, 24(a0)
; ZBA-NEXT: sw a4, 140(a0)
; ZBA-NEXT: ret
entry:
%add = add nsw i32 %a, 5
%cmp = icmp sgt i32 %x, 0
Expand All @@ -118,23 +166,40 @@ entry:
}

define void @add_sext_shl_moreOneUse_add_inSelect_addexceedsign12(ptr %array1, i32 signext %a, i32 %b, i32 signext %x) {
; RV64-LABEL: add_sext_shl_moreOneUse_add_inSelect_addexceedsign12:
; RV64: # %bb.0: # %entry
; RV64-NEXT: addi a4, a1, 2047
; RV64-NEXT: lui a5, 2
; RV64-NEXT: slli a6, a1, 2
; RV64-NEXT: addi a1, a4, 1
; RV64-NEXT: add a0, a0, a6
; RV64-NEXT: add a0, a0, a5
; RV64-NEXT: mv a4, a1
; RV64-NEXT: bgtz a3, .LBB4_2
; RV64-NEXT: # %bb.1: # %entry
; RV64-NEXT: mv a4, a2
; RV64-NEXT: .LBB4_2: # %entry
; RV64-NEXT: sw a4, 0(a0)
; RV64-NEXT: sw a4, 4(a0)
; RV64-NEXT: sw a1, 120(a0)
; RV64-NEXT: ret
; NO-ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect_addexceedsign12:
; NO-ZBA: # %bb.0: # %entry
; NO-ZBA-NEXT: addi a4, a1, 2047
; NO-ZBA-NEXT: lui a5, 2
; NO-ZBA-NEXT: slli a6, a1, 2
; NO-ZBA-NEXT: addi a1, a4, 1
; NO-ZBA-NEXT: add a0, a0, a6
; NO-ZBA-NEXT: add a0, a0, a5
; NO-ZBA-NEXT: mv a4, a1
; NO-ZBA-NEXT: bgtz a3, .LBB4_2
; NO-ZBA-NEXT: # %bb.1: # %entry
; NO-ZBA-NEXT: mv a4, a2
; NO-ZBA-NEXT: .LBB4_2: # %entry
; NO-ZBA-NEXT: sw a4, 0(a0)
; NO-ZBA-NEXT: sw a4, 4(a0)
; NO-ZBA-NEXT: sw a1, 120(a0)
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_sext_shl_moreOneUse_add_inSelect_addexceedsign12:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a4, a1, 2047
; ZBA-NEXT: lui a5, 2
; ZBA-NEXT: addi a4, a4, 1
; ZBA-NEXT: sh2add a0, a1, a0
; ZBA-NEXT: add a0, a0, a5
; ZBA-NEXT: mv a1, a4
; ZBA-NEXT: bgtz a3, .LBB4_2
; ZBA-NEXT: # %bb.1: # %entry
; ZBA-NEXT: mv a1, a2
; ZBA-NEXT: .LBB4_2: # %entry
; ZBA-NEXT: sw a1, 0(a0)
; ZBA-NEXT: sw a1, 4(a0)
; ZBA-NEXT: sw a4, 120(a0)
; ZBA-NEXT: ret
entry:
%add = add nsw i32 %a, 2048
%cmp = icmp sgt i32 %x, 0
Expand All @@ -152,20 +217,34 @@ entry:
}

define void @add_shl_moreOneUse_inSelect(ptr %array1, i64 %a, i64 %b, i64 %x) {
; RV64-LABEL: add_shl_moreOneUse_inSelect:
; RV64: # %bb.0: # %entry
; RV64-NEXT: addi a4, a1, 5
; RV64-NEXT: mv a5, a4
; RV64-NEXT: bgtz a3, .LBB5_2
; RV64-NEXT: # %bb.1: # %entry
; RV64-NEXT: mv a5, a2
; RV64-NEXT: .LBB5_2: # %entry
; RV64-NEXT: slli a1, a1, 3
; RV64-NEXT: add a0, a1, a0
; RV64-NEXT: sd a5, 40(a0)
; RV64-NEXT: sd a5, 48(a0)
; RV64-NEXT: sd a4, 280(a0)
; RV64-NEXT: ret
; NO-ZBA-LABEL: add_shl_moreOneUse_inSelect:
; NO-ZBA: # %bb.0: # %entry
; NO-ZBA-NEXT: addi a4, a1, 5
; NO-ZBA-NEXT: mv a5, a4
; NO-ZBA-NEXT: bgtz a3, .LBB5_2
; NO-ZBA-NEXT: # %bb.1: # %entry
; NO-ZBA-NEXT: mv a5, a2
; NO-ZBA-NEXT: .LBB5_2: # %entry
; NO-ZBA-NEXT: slli a1, a1, 3
; NO-ZBA-NEXT: add a0, a1, a0
; NO-ZBA-NEXT: sd a5, 40(a0)
; NO-ZBA-NEXT: sd a5, 48(a0)
; NO-ZBA-NEXT: sd a4, 280(a0)
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_shl_moreOneUse_inSelect:
; ZBA: # %bb.0: # %entry
; ZBA-NEXT: addi a4, a1, 5
; ZBA-NEXT: mv a5, a4
; ZBA-NEXT: bgtz a3, .LBB5_2
; ZBA-NEXT: # %bb.1: # %entry
; ZBA-NEXT: mv a5, a2
; ZBA-NEXT: .LBB5_2: # %entry
; ZBA-NEXT: sh3add a0, a1, a0
; ZBA-NEXT: sd a5, 40(a0)
; ZBA-NEXT: sd a5, 48(a0)
; ZBA-NEXT: sd a4, 280(a0)
; ZBA-NEXT: ret
entry:
%add = add nsw i64 %a, 5
%cmp = icmp sgt i64 %x, 0
Expand All @@ -180,3 +259,90 @@ entry:
store i64 %add, ptr %arrayidx6
ret void
}

define i64 @add_shl_moreOneUse_sh1add(i64 %x) {
; NO-ZBA-LABEL: add_shl_moreOneUse_sh1add:
; NO-ZBA: # %bb.0:
; NO-ZBA-NEXT: ori a1, a0, 1
; NO-ZBA-NEXT: slli a0, a0, 1
; NO-ZBA-NEXT: ori a0, a0, 2
; NO-ZBA-NEXT: add a0, a0, a1
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_shl_moreOneUse_sh1add:
; ZBA: # %bb.0:
; ZBA-NEXT: ori a0, a0, 1
; ZBA-NEXT: sh1add a0, a0, a0
; ZBA-NEXT: ret
%or = or i64 %x, 1
%mul = shl i64 %or, 1
%add = add i64 %mul, %or
ret i64 %add
}

define i64 @add_shl_moreOneUse_sh2add(i64 %x) {
; NO-ZBA-LABEL: add_shl_moreOneUse_sh2add:
; NO-ZBA: # %bb.0:
; NO-ZBA-NEXT: ori a1, a0, 1
; NO-ZBA-NEXT: slli a0, a0, 2
; NO-ZBA-NEXT: ori a0, a0, 4
; NO-ZBA-NEXT: add a0, a0, a1
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_shl_moreOneUse_sh2add:
; ZBA: # %bb.0:
; ZBA-NEXT: ori a0, a0, 1
; ZBA-NEXT: sh2add a0, a0, a0
; ZBA-NEXT: ret
%or = or i64 %x, 1
%mul = shl i64 %or, 2
%add = add i64 %mul, %or
ret i64 %add
}

define i64 @add_shl_moreOneUse_sh3add(i64 %x) {
; NO-ZBA-LABEL: add_shl_moreOneUse_sh3add:
; NO-ZBA: # %bb.0:
; NO-ZBA-NEXT: ori a1, a0, 1
; NO-ZBA-NEXT: slli a0, a0, 3
; NO-ZBA-NEXT: ori a0, a0, 8
; NO-ZBA-NEXT: add a0, a0, a1
; NO-ZBA-NEXT: ret
;
; ZBA-LABEL: add_shl_moreOneUse_sh3add:
; ZBA: # %bb.0:
; ZBA-NEXT: ori a0, a0, 1
; ZBA-NEXT: sh3add a0, a0, a0
; ZBA-NEXT: ret
%or = or i64 %x, 1
%mul = shl i64 %or, 3
%add = add i64 %mul, %or
ret i64 %add
}

define i64 @add_shl_moreOneUse_sh4add(i64 %x) {
; RV64-LABEL: add_shl_moreOneUse_sh4add:
; RV64: # %bb.0:
; RV64-NEXT: ori a1, a0, 1
; RV64-NEXT: slli a0, a0, 4
; RV64-NEXT: ori a0, a0, 16
; RV64-NEXT: add a0, a0, a1
; RV64-NEXT: ret
%or = or i64 %x, 1
%mul = shl i64 %or, 4
%add = add i64 %mul, %or
ret i64 %add
}

define i64 @add_shl_rhs_constant(i64 %x, i64 %y) {
; RV64-LABEL: add_shl_rhs_constant:
; RV64: # %bb.0:
; RV64-NEXT: add a0, a0, a1
; RV64-NEXT: slli a0, a0, 3
; RV64-NEXT: ret
%a = add i64 %x, 1
%b = add i64 %y, %a
%c = shl i64 %b, 3
%d = add i64 %c, -8
ret i64 %d
}
Loading
Loading