Skip to content

Commit

Permalink
[RISCV] Add FeaturePredictableSelectIsExpensive
Browse files Browse the repository at this point in the history
This information is used in CGP/SelectOpt to decide when to convert
selects into branches.

Reviewers: dtcxzyw, mgudim, asb, preames, topperc, lukel97

Reviewed By: dtcxzyw, topperc, lukel97

Pull Request: #97708
  • Loading branch information
wangpc-pp authored Jul 5, 2024
1 parent 9e21174 commit 23aff11
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 0 deletions.
4 changes: 4 additions & 0 deletions llvm/lib/Target/RISCV/RISCVFeatures.td
Original file line number Diff line number Diff line change
Expand Up @@ -1262,6 +1262,10 @@ def FeatureUnalignedVectorMem
def FeaturePostRAScheduler : SubtargetFeature<"use-postra-scheduler",
"UsePostRAScheduler", "true", "Schedule again after register allocation">;

def FeaturePredictableSelectIsExpensive
: SubtargetFeature<"predictable-select-expensive", "PredictableSelectIsExpensive", "true",
"Prefer likely predicted branches over selects">;

def TuneNoOptimizedZeroStrideLoad
: SubtargetFeature<"no-optimized-zero-stride-load", "HasOptimizedZeroStrideLoad",
"false", "Hasn't optimized (perform fewer memory operations)"
Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/RISCV/RISCVISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1518,6 +1518,11 @@ RISCVTargetLowering::RISCVTargetLowering(const TargetMachine &TM,

// Disable strict node mutation.
IsStrictFPEnabled = true;

// Let the subtarget decide if a predictable select is more expensive than the
// corresponding branch. This information is used in CGP/SelectOpt to decide
// when to convert selects into branches.
PredictableSelectIsExpensive = Subtarget.predictableSelectIsExpensive();
}

EVT RISCVTargetLowering::getSetCCResultType(const DataLayout &DL,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5
; RUN: llc -mtriple=riscv64 -mattr=+zicond < %s | FileCheck %s --check-prefixes=CHECK,CHEAP
; RUN: llc -mtriple=riscv64 -mattr=+zicond,+predictable-select-expensive < %s | FileCheck %s --check-prefixes=CHECK,EXPENSIVE

; Test has not predictable select, which should not be transformed to a branch
define i32 @test1(i32 %a) {
; CHECK-LABEL: test1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: sext.w a1, a0
; CHECK-NEXT: slti a1, a1, 1
; CHECK-NEXT: addiw a0, a0, -1
; CHECK-NEXT: czero.nez a0, a0, a1
; CHECK-NEXT: ret
entry:
%cmp = icmp slt i32 %a, 1
%dec = sub i32 %a, 1
%res = select i1 %cmp, i32 0, i32 %dec, !prof !0
ret i32 %res
}

; Test has highly predictable select according to profile data,
; which should be transformed to a branch on cores with enabled FeaturePredictableSelectIsExpensive
define i32 @test2(i32 %a) {
; CHEAP-LABEL: test2:
; CHEAP: # %bb.0: # %entry
; CHEAP-NEXT: sext.w a1, a0
; CHEAP-NEXT: slti a1, a1, 1
; CHEAP-NEXT: addiw a0, a0, -1
; CHEAP-NEXT: czero.nez a0, a0, a1
; CHEAP-NEXT: ret
;
; EXPENSIVE-LABEL: test2:
; EXPENSIVE: # %bb.0: # %entry
; EXPENSIVE-NEXT: sext.w a1, a0
; EXPENSIVE-NEXT: blez a1, .LBB1_2
; EXPENSIVE-NEXT: # %bb.1: # %select.false
; EXPENSIVE-NEXT: addiw a0, a0, -1
; EXPENSIVE-NEXT: ret
; EXPENSIVE-NEXT: .LBB1_2:
; EXPENSIVE-NEXT: li a0, 0
; EXPENSIVE-NEXT: ret
entry:
%cmp = icmp slt i32 %a, 1
%dec = sub i32 %a, 1
%res = select i1 %cmp, i32 0, i32 %dec, !prof !1
ret i32 %res
}

!0 = !{!"branch_weights", i32 1, i32 1}
!1 = !{!"branch_weights", i32 1, i32 1000}

0 comments on commit 23aff11

Please sign in to comment.