Skip to content

Commit 6dd14c8

Browse files
wzssyqaqethu
andauthored
MIPS: Implements MipsTTIImpl::isLSRCostLess using Insns as first (#133068)
So that LoopStrengthReduce can work for MIPS. The code is copied from RISC-V. --------- Co-authored-by: qethu <[email protected]>
1 parent c3e08c8 commit 6dd14c8

File tree

3 files changed

+88
-0
lines changed

3 files changed

+88
-0
lines changed

llvm/lib/Target/Mips/MipsTargetTransformInfo.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,3 +15,16 @@ bool MipsTTIImpl::hasDivRemOp(Type *DataType, bool IsSigned) {
1515
return TLI->isOperationLegalOrCustom(IsSigned ? ISD::SDIVREM : ISD::UDIVREM,
1616
VT);
1717
}
18+
19+
bool MipsTTIImpl::isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
20+
const TargetTransformInfo::LSRCost &C2) {
21+
// MIPS specific here are "instruction number 1st priority".
22+
// If we need to emit adds inside the loop to add up base registers, then
23+
// we need at least one extra temporary register.
24+
unsigned C1NumRegs = C1.NumRegs + (C1.NumBaseAdds != 0);
25+
unsigned C2NumRegs = C2.NumRegs + (C2.NumBaseAdds != 0);
26+
return std::tie(C1.Insns, C1NumRegs, C1.AddRecCost, C1.NumIVMuls,
27+
C1.NumBaseAdds, C1.ScaleCost, C1.ImmCost, C1.SetupCost) <
28+
std::tie(C2.Insns, C2NumRegs, C2.AddRecCost, C2.NumIVMuls,
29+
C2.NumBaseAdds, C2.ScaleCost, C2.ImmCost, C2.SetupCost);
30+
}

llvm/lib/Target/Mips/MipsTargetTransformInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ class MipsTTIImpl : public BasicTTIImplBase<MipsTTIImpl> {
3333
TLI(ST->getTargetLowering()) {}
3434

3535
bool hasDivRemOp(Type *DataType, bool IsSigned);
36+
37+
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
38+
const TargetTransformInfo::LSRCost &C2);
3639
};
3740

3841
} // end namespace llvm
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
2+
; RUN: opt < %s -passes=loop-reduce -S | FileCheck %s
3+
4+
target datalayout = "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64"
5+
target triple = "mips-unknown-linux-gnu"
6+
7+
@x = dso_local local_unnamed_addr global [128000 x i32] zeroinitializer, align 4
8+
9+
; Function Attrs: nofree norecurse nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
10+
define dso_local void @in128000(i32 noundef signext %k, i32 noundef signext %n) local_unnamed_addr #0 {
11+
; CHECK-LABEL: define dso_local void @in128000(
12+
; CHECK-SAME: i32 noundef signext [[K:%.*]], i32 noundef signext [[N:%.*]]) local_unnamed_addr {
13+
; CHECK-NEXT: [[ENTRY:.*]]:
14+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
15+
; CHECK: [[FOR_COND_CLEANUP:.*]]:
16+
; CHECK-NEXT: ret void
17+
; CHECK: [[FOR_BODY]]:
18+
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP:%.*]], %[[FOR_BODY]] ], [ @x, %[[ENTRY]] ]
19+
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[FOR_BODY]] ], [ 128000, %[[ENTRY]] ]
20+
; CHECK-NEXT: store i32 [[K]], ptr [[LSR_IV1]], align 4
21+
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -1
22+
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV1]], i32 4
23+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 0
24+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
25+
;
26+
entry:
27+
br label %for.body
28+
29+
for.cond.cleanup: ; preds = %for.body
30+
ret void
31+
32+
for.body: ; preds = %entry, %for.body
33+
%i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
34+
%arrayidx = getelementptr inbounds nuw [128000 x i32], ptr @x, i32 0, i32 %i.03
35+
store i32 %k, ptr %arrayidx, align 4
36+
%inc = add nuw nsw i32 %i.03, 1
37+
%exitcond.not = icmp eq i32 %inc, 128000
38+
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
39+
}
40+
41+
; Function Attrs: nofree norecurse nosync nounwind memory(write, argmem: none, inaccessiblemem: none)
42+
define dso_local void @in1000(i32 noundef signext %k, i32 noundef signext %n) local_unnamed_addr #0 {
43+
; CHECK-LABEL: define dso_local void @in1000(
44+
; CHECK-SAME: i32 noundef signext [[K:%.*]], i32 noundef signext [[N:%.*]]) local_unnamed_addr {
45+
; CHECK-NEXT: [[ENTRY:.*]]:
46+
; CHECK-NEXT: br label %[[FOR_BODY:.*]]
47+
; CHECK: [[FOR_COND_CLEANUP:.*]]:
48+
; CHECK-NEXT: ret void
49+
; CHECK: [[FOR_BODY]]:
50+
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP:%.*]], %[[FOR_BODY]] ], [ @x, %[[ENTRY]] ]
51+
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i32 [ [[LSR_IV_NEXT:%.*]], %[[FOR_BODY]] ], [ 1000, %[[ENTRY]] ]
52+
; CHECK-NEXT: store i32 [[K]], ptr [[LSR_IV1]], align 4
53+
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i32 [[LSR_IV]], -1
54+
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV1]], i32 4
55+
; CHECK-NEXT: [[EXITCOND_NOT:%.*]] = icmp eq i32 [[LSR_IV_NEXT]], 0
56+
; CHECK-NEXT: br i1 [[EXITCOND_NOT]], label %[[FOR_COND_CLEANUP]], label %[[FOR_BODY]]
57+
;
58+
entry:
59+
br label %for.body
60+
61+
for.cond.cleanup: ; preds = %for.body
62+
ret void
63+
64+
for.body: ; preds = %entry, %for.body
65+
%i.03 = phi i32 [ 0, %entry ], [ %inc, %for.body ]
66+
%arrayidx = getelementptr inbounds nuw [128000 x i32], ptr @x, i32 0, i32 %i.03
67+
store i32 %k, ptr %arrayidx, align 4
68+
%inc = add nuw nsw i32 %i.03, 1
69+
%exitcond.not = icmp eq i32 %inc, 1000
70+
br i1 %exitcond.not, label %for.cond.cleanup, label %for.body
71+
}
72+

0 commit comments

Comments
 (0)