Skip to content

Commit d901485

Browse files
authored
[Mips] Add compact branch patterns for MipsR6 (#171131)
Added patterns for combining set and branch into one compact branch The patterns are disabled if -mips-compact-branches=never
1 parent c9ad896 commit d901485

File tree

11 files changed

+656
-26
lines changed

11 files changed

+656
-26
lines changed

llvm/lib/Target/Mips/Mips.td

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,10 @@ def FeatureStrictAlign
212212
: SubtargetFeature<"strict-align", "StrictAlign", "true",
213213
"Disable unaligned load store for r6">;
214214

215+
def FeatureUseCompactBranches
216+
: SubtargetFeature<"use-compact-branches", "UseCompactBranches", "true",
217+
"Use compact branch instructions for MIPS32R6/MIPS64R6">;
218+
215219
//===----------------------------------------------------------------------===//
216220
// Mips Instruction Predicate Definitions.
217221
//===----------------------------------------------------------------------===//
@@ -220,6 +224,8 @@ def IsPTR64bit : Predicate<"Subtarget->isABI_N64()">,
220224
AssemblerPredicate<(all_of FeaturePTR64Bit)>;
221225
def IsPTR32bit : Predicate<"!Subtarget->isABI_N64()">,
222226
AssemblerPredicate<(all_of (not FeaturePTR64Bit))>;
227+
def UseCompactBranches : Predicate<"Subtarget->useCompactBranches()">,
228+
AssemblerPredicate<(all_of FeatureUseCompactBranches)>;
223229

224230
//===----------------------------------------------------------------------===//
225231
// HwModes

llvm/lib/Target/Mips/Mips32r6InstrInfo.td

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1226,3 +1226,41 @@ let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
12261226
GPR32Opnd>,
12271227
ISA_MIPS32R6;
12281228
}
1229+
1230+
// Combining branch and set instructions into one compact branch instruction
1231+
let AdditionalPredicates = [NotInMicroMips, UseCompactBranches] in {
1232+
def : MipsPat<(brcond (i32 (setlt i32:$rs, 0)), bb:$offset),
1233+
(BLTZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1234+
def : MipsPat<(brcond (i32 (setlt i32:$rs, 1)), bb:$offset),
1235+
(BLEZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1236+
def : MipsPat<(brcond (i32 (setge i32:$rs, 0)), bb:$offset),
1237+
(BGEZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1238+
def : MipsPat<(brcond (i32 (setge i32:$rs, 1)), bb:$offset),
1239+
(BGTZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1240+
def : MipsPat<(brcond (i32 (setgt i32:$rs, 0)), bb:$offset),
1241+
(BGTZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1242+
def : MipsPat<(brcond (i32 (setgt i32:$rs, -1)), bb:$offset),
1243+
(BGEZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1244+
def : MipsPat<(brcond (i32 (setle i32:$rs, 0)), bb:$offset),
1245+
(BLEZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1246+
def : MipsPat<(brcond (i32 (setle i32:$rs, -1)), bb:$offset),
1247+
(BLTZC GPR32Opnd:$rs, bb:$offset)>, ISA_MIPS32R6;
1248+
1249+
def : MipsPat<(brcond (i32 (setlt GPR32:$rs, GPR32:$rt)), bb:$offset),
1250+
(BLTC GPR32:$rs, GPR32:$rt, bb:$offset)>, ISA_MIPS32R6;
1251+
def : MipsPat<(brcond (i32 (setge GPR32:$rs, GPR32:$rt)), bb:$offset),
1252+
(BGEC GPR32:$rs, GPR32:$rt, bb:$offset)>, ISA_MIPS32R6;
1253+
def : MipsPat<(brcond (i32 (setgt GPR32:$rs, GPR32:$rt)), bb:$offset),
1254+
(BLTC GPR32:$rt, GPR32:$rs, bb:$offset)>, ISA_MIPS32R6;
1255+
def : MipsPat<(brcond (i32 (setle GPR32:$rs, GPR32:$rt)), bb:$offset),
1256+
(BGEC GPR32:$rt, GPR32:$rs, bb:$offset)>, ISA_MIPS32R6;
1257+
1258+
def : MipsPat<(brcond (i32 (setult GPR32:$rs, GPR32:$rt)), bb:$offset),
1259+
(BLTUC GPR32:$rs, GPR32:$rt, bb:$offset)>, ISA_MIPS32R6;
1260+
def : MipsPat<(brcond (i32 (setuge GPR32:$rs, GPR32:$rt)), bb:$offset),
1261+
(BGEUC GPR32:$rs, GPR32:$rt, bb:$offset)>, ISA_MIPS32R6;
1262+
def : MipsPat<(brcond (i32 (setugt GPR32:$rs, GPR32:$rt)), bb:$offset),
1263+
(BLTUC GPR32:$rt, GPR32:$rs, bb:$offset)>, ISA_MIPS32R6;
1264+
def : MipsPat<(brcond (i32 (setule GPR32:$rs, GPR32:$rt)), bb:$offset),
1265+
(BGEUC GPR32:$rt, GPR32:$rs, bb:$offset)>, ISA_MIPS32R6;
1266+
}

llvm/lib/Target/Mips/Mips64r6InstrInfo.td

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,3 +338,41 @@ let AdditionalPredicates = [NotInMips16Mode, NotInMicroMips,
338338
GPR64Opnd>,
339339
ISA_MIPS64R6;
340340
}
341+
342+
// Combining branch and set instructions into one compact branch instruction
343+
let AdditionalPredicates = [NotInMicroMips, UseCompactBranches] in {
344+
def : MipsPat<(brcond (i32 (setlt i64:$rs, 0)), bb:$offset),
345+
(BLTZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
346+
def : MipsPat<(brcond (i32 (setlt i64:$rs, 1)), bb:$offset),
347+
(BLEZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
348+
def : MipsPat<(brcond (i32 (setge i64:$rs, 0)), bb:$offset),
349+
(BGEZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
350+
def : MipsPat<(brcond (i32 (setge i64:$rs, 1)), bb:$offset),
351+
(BGTZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
352+
def : MipsPat<(brcond (i32 (setgt i64:$rs, 0)), bb:$offset),
353+
(BGTZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
354+
def : MipsPat<(brcond (i32 (setgt i64:$rs, -1)), bb:$offset),
355+
(BGEZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
356+
def : MipsPat<(brcond (i32 (setle i64:$rs, 0)), bb:$offset),
357+
(BLEZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
358+
def : MipsPat<(brcond (i32 (setle i64:$rs, -1)), bb:$offset),
359+
(BLTZC64 GPR64Opnd:$rs, bb:$offset)>, ISA_MIPS64R6;
360+
361+
def : MipsPat<(brcond (i32 (setlt GPR64:$rs, GPR64:$rt)), bb:$offset),
362+
(BLTC64 GPR64:$rs, GPR64:$rt, bb:$offset)>, ISA_MIPS64R6;
363+
def : MipsPat<(brcond (i32 (setge GPR64:$rs, GPR64:$rt)), bb:$offset),
364+
(BGEC64 GPR64:$rs, GPR64:$rt, bb:$offset)>, ISA_MIPS64R6;
365+
def : MipsPat<(brcond (i32 (setgt GPR64:$rs, GPR64:$rt)), bb:$offset),
366+
(BLTC64 GPR64:$rt, GPR64:$rs, bb:$offset)>, ISA_MIPS64R6;
367+
def : MipsPat<(brcond (i32 (setle GPR64:$rs, GPR64:$rt)), bb:$offset),
368+
(BGEC64 GPR64:$rt, GPR64:$rs, bb:$offset)>, ISA_MIPS64R6;
369+
370+
def : MipsPat<(brcond (i32 (setult GPR64:$rs, GPR64:$rt)), bb:$offset),
371+
(BLTUC64 GPR64:$rs, GPR64:$rt, bb:$offset)>, ISA_MIPS64R6;
372+
def : MipsPat<(brcond (i32 (setuge GPR64:$rs, GPR64:$rt)), bb:$offset),
373+
(BGEUC64 GPR64:$rs, GPR64:$rt, bb:$offset)>, ISA_MIPS64R6;
374+
def : MipsPat<(brcond (i32 (setugt GPR64:$rs, GPR64:$rt)), bb:$offset),
375+
(BLTUC64 GPR64:$rt, GPR64:$rs, bb:$offset)>, ISA_MIPS64R6;
376+
def : MipsPat<(brcond (i32 (setule GPR64:$rs, GPR64:$rt)), bb:$offset),
377+
(BGEUC64 GPR64:$rt, GPR64:$rs, bb:$offset)>, ISA_MIPS64R6;
378+
}

llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -77,25 +77,7 @@ static cl::opt<bool> DisableBackwardSearch(
7777
cl::desc("Disallow MIPS delay filler to search backward."),
7878
cl::Hidden);
7979

80-
enum CompactBranchPolicy {
81-
CB_Never, ///< The policy 'never' may in some circumstances or for some
82-
///< ISAs not be absolutely adhered to.
83-
CB_Optimal, ///< Optimal is the default and will produce compact branches
84-
///< when delay slots cannot be filled.
85-
CB_Always ///< 'always' may in some circumstances may not be
86-
///< absolutely adhered to there may not be a corresponding
87-
///< compact form of a branch.
88-
};
89-
90-
static cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy(
91-
"mips-compact-branches", cl::Optional, cl::init(CB_Optimal),
92-
cl::desc("MIPS Specific: Compact branch policy."),
93-
cl::values(clEnumValN(CB_Never, "never",
94-
"Do not use compact branches if possible."),
95-
clEnumValN(CB_Optimal, "optimal",
96-
"Use compact branches where appropriate (default)."),
97-
clEnumValN(CB_Always, "always",
98-
"Always use compact branches if possible.")));
80+
extern cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy;
9981

10082
namespace {
10183

llvm/lib/Target/Mips/MipsSubtarget.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,16 @@
2727

2828
using namespace llvm;
2929

30+
cl::opt<CompactBranchPolicy> MipsCompactBranchPolicy(
31+
"mips-compact-branches", cl::Optional, cl::init(CB_Optimal),
32+
cl::desc("MIPS Specific: Compact branch policy."),
33+
cl::values(clEnumValN(CB_Never, "never",
34+
"Do not use compact branches if possible."),
35+
clEnumValN(CB_Optimal, "optimal",
36+
"Use compact branches where appropriate (default)."),
37+
clEnumValN(CB_Always, "always",
38+
"Always use compact branches if possible.")));
39+
3040
#define DEBUG_TYPE "mips-subtarget"
3141

3242
#define GET_SUBTARGETINFO_TARGET_DESC
@@ -84,6 +94,7 @@ MipsSubtarget::MipsSubtarget(const Triple &TT, StringRef CPU, StringRef FS,
8494
UseTCCInDIV(false), HasSym32(false), HasEVA(false), DisableMadd4(false),
8595
HasMT(false), HasCRC(false), HasVirt(false), HasGINV(false),
8696
UseIndirectJumpsHazard(false), StrictAlign(false),
97+
UseCompactBranches(MipsCompactBranchPolicy != CB_Never),
8798
StackAlignOverride(StackAlignOverride), TM(TM), TargetTriple(TT),
8899
InstrInfo(
89100
MipsInstrInfo::create(initializeSubtargetDependencies(CPU, FS, TM))),

llvm/lib/Target/Mips/MipsSubtarget.h

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,16 @@
3232
namespace llvm {
3333
class StringRef;
3434

35+
enum CompactBranchPolicy {
36+
CB_Never, ///< The policy 'never' may in some circumstances or for some
37+
///< ISAs not be absolutely adhered to.
38+
CB_Optimal, ///< Optimal is the default and will produce compact branches
39+
///< when appropriate.
40+
CB_Always ///< 'always' may in some circumstances may not be
41+
///< absolutely adhered to, there may not be a corresponding
42+
///< compact form of a branch.
43+
};
44+
3545
class MipsTargetMachine;
3646

3747
class MipsSubtarget : public MipsGenSubtargetInfo {
@@ -201,6 +211,9 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
201211
// Disable unaligned load store for r6.
202212
bool StrictAlign;
203213

214+
// Use compact branch instructions for R6.
215+
bool UseCompactBranches = true;
216+
204217
/// The minimum alignment known to hold of the stack frame on
205218
/// entry to the function and which must be maintained by every function.
206219
Align stackAlignment;
@@ -336,6 +349,10 @@ class MipsSubtarget : public MipsGenSubtargetInfo {
336349
}
337350
bool useSmallSection() const { return UseSmallSection; }
338351

352+
bool useCompactBranches() const {
353+
return UseCompactBranches && hasMips32r6();
354+
}
355+
339356
bool hasStandardEncoding() const { return !InMips16Mode && !InMicroMipsMode; }
340357

341358
bool useSoftFloat() const { return IsSoftFloat; }

llvm/test/CodeGen/Mips/branch-relaxation-with-hazard.ll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,13 @@ define i32 @main(i32 signext %argc, ptr %argv) {
1717
; CHECK-PIC: addiu
1818
; CHECK-PIC: jrc
1919
; CHECK-PIC: bc
20-
; CHECK-PIC: bnezc
20+
; CHECK-PIC: bltc
2121
; CHECK-PIC: nop
2222
; CHECK-PIC: bc
2323

2424
; CHECK-STATIC: bc
2525
; CHECK-STATIC: j
26-
; CHECK-STATIC: bnezc
26+
; CHECK-STATIC: bltc
2727
; CHECK-STATIC: nop
2828
; CHECK-STATIC: j
2929
entry:
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 6
2+
; RUN: llc -mtriple=mipsel -mcpu=mips32r6 -mips-compact-branches=never < %s | FileCheck %s --check-prefix=MIPS32R6
3+
; RUN: llc -mtriple=mips64el -mcpu=mips64r6 -mips-compact-branches=never < %s | FileCheck %s --check-prefix=MIPS64R6
4+
5+
;; Test checking we respect mips-compact-branches=never
6+
;; The patterns set + branch should be disabled and not emit compact branches
7+
8+
define void @test_slt_never(i32 %a, i32 %b) {
9+
; MIPS32R6-LABEL: test_slt_never:
10+
; MIPS32R6: # %bb.0:
11+
; MIPS32R6-NEXT: slt $1, $4, $5
12+
; MIPS32R6-NEXT: beqz $1, $BB0_2
13+
; MIPS32R6-NEXT: nop
14+
; MIPS32R6-NEXT: # %bb.1: # %t
15+
; MIPS32R6-NEXT: jr $ra
16+
; MIPS32R6-NEXT: nop
17+
; MIPS32R6-NEXT: $BB0_2: # %f
18+
; MIPS32R6-NEXT: jr $ra
19+
; MIPS32R6-NEXT: nop
20+
;
21+
; MIPS64R6-LABEL: test_slt_never:
22+
; MIPS64R6: # %bb.0:
23+
; MIPS64R6-NEXT: sll $1, $5, 0
24+
; MIPS64R6-NEXT: sll $2, $4, 0
25+
; MIPS64R6-NEXT: slt $1, $2, $1
26+
; MIPS64R6-NEXT: beqz $1, .LBB0_2
27+
; MIPS64R6-NEXT: nop
28+
; MIPS64R6-NEXT: # %bb.1: # %t
29+
; MIPS64R6-NEXT: jr $ra
30+
; MIPS64R6-NEXT: nop
31+
; MIPS64R6-NEXT: .LBB0_2: # %f
32+
; MIPS64R6-NEXT: jr $ra
33+
; MIPS64R6-NEXT: nop
34+
%c = icmp slt i32 %a, %b
35+
br i1 %c, label %t, label %f
36+
t:
37+
ret void
38+
f:
39+
ret void
40+
}
41+
42+
define void @test_ult_never(i32 %a, i32 %b) {
43+
; MIPS32R6-LABEL: test_ult_never:
44+
; MIPS32R6: # %bb.0:
45+
; MIPS32R6-NEXT: sltu $1, $4, $5
46+
; MIPS32R6-NEXT: beqz $1, $BB1_2
47+
; MIPS32R6-NEXT: nop
48+
; MIPS32R6-NEXT: # %bb.1: # %t
49+
; MIPS32R6-NEXT: jr $ra
50+
; MIPS32R6-NEXT: nop
51+
; MIPS32R6-NEXT: $BB1_2: # %f
52+
; MIPS32R6-NEXT: jr $ra
53+
; MIPS32R6-NEXT: nop
54+
;
55+
; MIPS64R6-LABEL: test_ult_never:
56+
; MIPS64R6: # %bb.0:
57+
; MIPS64R6-NEXT: sll $1, $5, 0
58+
; MIPS64R6-NEXT: sll $2, $4, 0
59+
; MIPS64R6-NEXT: sltu $1, $2, $1
60+
; MIPS64R6-NEXT: beqz $1, .LBB1_2
61+
; MIPS64R6-NEXT: nop
62+
; MIPS64R6-NEXT: # %bb.1: # %t
63+
; MIPS64R6-NEXT: jr $ra
64+
; MIPS64R6-NEXT: nop
65+
; MIPS64R6-NEXT: .LBB1_2: # %f
66+
; MIPS64R6-NEXT: jr $ra
67+
; MIPS64R6-NEXT: nop
68+
%c = icmp ult i32 %a, %b
69+
br i1 %c, label %t, label %f
70+
t:
71+
ret void
72+
f:
73+
ret void
74+
}
75+

0 commit comments

Comments
 (0)