[LSR][TTI][RISCV] Enable terminator folding for RISC-V

If looking for a miscompile revert candidate, look here!

The transform being enabled prefers comparing to a loop invariant
exit value for a secondary IV over using an otherwise dead primary
IV.  This increases register pressure (by requiring the exit value
to be live through the loop), but reduces the number of instructions
within the loop by one.

On RISC-V which has a large number of scalar registers, this is
generally a profitable transform.  We loose the ability to use a beqz
on what is typically a count down IV, and pay the cost of computing
the exit value on the secondary IV in the loop preheader, but save
an add or sub in the loop body.  For anything except an extremely
short running loop, or one with extreme register pressure, this is
profitable.  On spec2017, we see a 0.42% geomean improvement in
dynamic icount, with no individual workload regressing by more than
0.25%.

Code size wise, we trade a (possibly compressible) beqz and a (possibly
compressible) addi for a uncompressible beq.  We also add instructions
in the preheader.  Net result is a slight regression overall, but
neutral or better inside the loop.

Previous versions of this transform had numerous cornercase correctness
bugs.  All of them ones I can spot by inspection have been fixed, and I
have run this through all of spec2017, but there may be further issues
lurking.  Adding uses to an IV is a fraught thing to do given poison
semantics, so this transform is somewhat inherently risky.

This patch is a reworked version of D134893 by @eop.  That patch has
been abandoned since May, so I picked it up, reworked it a bit, and
am landing it.
This commit is contained in:
Philip Reames
2023-11-29 10:59:17 -08:00
committed by Philip Reames
parent 002c54a2e6
commit e947f95337
14 changed files with 759 additions and 734 deletions

View File

@@ -718,6 +718,11 @@ public:
/// cost should return false, otherwise return true.
bool isNumRegsMajorCostOfLSR() const;
/// Return true if LSR should attempts to replace a use of an otherwise dead
/// primary IV in the latch condition with another IV available in the loop.
/// When successful, makes the primary IV dead.
bool shouldFoldTerminatingConditionAfterLSR() const;
/// \returns true if LSR should not optimize a chain that includes \p I.
bool isProfitableLSRChainElement(Instruction *I) const;
@@ -1786,6 +1791,7 @@ public:
virtual bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
const TargetTransformInfo::LSRCost &C2) = 0;
virtual bool isNumRegsMajorCostOfLSR() = 0;
virtual bool shouldFoldTerminatingConditionAfterLSR() const = 0;
virtual bool isProfitableLSRChainElement(Instruction *I) = 0;
virtual bool canMacroFuseCmp() = 0;
virtual bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE,
@@ -2239,6 +2245,9 @@ public:
bool isNumRegsMajorCostOfLSR() override {
return Impl.isNumRegsMajorCostOfLSR();
}
bool shouldFoldTerminatingConditionAfterLSR() const override {
return Impl.shouldFoldTerminatingConditionAfterLSR();
}
bool isProfitableLSRChainElement(Instruction *I) override {
return Impl.isProfitableLSRChainElement(I);
}

View File

@@ -235,6 +235,8 @@ public:
bool isNumRegsMajorCostOfLSR() const { return true; }
bool shouldFoldTerminatingConditionAfterLSR() const { return false; }
bool isProfitableLSRChainElement(Instruction *I) const { return false; }
bool canMacroFuseCmp() const { return false; }

View File

@@ -382,6 +382,11 @@ public:
return TargetTransformInfoImplBase::isNumRegsMajorCostOfLSR();
}
bool shouldFoldTerminatingConditionAfterLSR() const {
return TargetTransformInfoImplBase::
shouldFoldTerminatingConditionAfterLSR();
}
bool isProfitableLSRChainElement(Instruction *I) {
return TargetTransformInfoImplBase::isProfitableLSRChainElement(I);
}

View File

@@ -413,6 +413,10 @@ bool TargetTransformInfo::isNumRegsMajorCostOfLSR() const {
return TTIImpl->isNumRegsMajorCostOfLSR();
}
bool TargetTransformInfo::shouldFoldTerminatingConditionAfterLSR() const {
return TTIImpl->shouldFoldTerminatingConditionAfterLSR();
}
bool TargetTransformInfo::isProfitableLSRChainElement(Instruction *I) const {
return TTIImpl->isProfitableLSRChainElement(I);
}

View File

@@ -357,6 +357,10 @@ public:
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
const TargetTransformInfo::LSRCost &C2);
bool shouldFoldTerminatingConditionAfterLSR() const {
return true;
}
};
} // end namespace llvm

View File

@@ -188,8 +188,8 @@ static cl::opt<unsigned> SetupCostDepthLimit(
"lsr-setupcost-depth-limit", cl::Hidden, cl::init(7),
cl::desc("The limit on recursion depth for LSRs setup cost"));
static cl::opt<bool> AllowTerminatingConditionFoldingAfterLSR(
"lsr-term-fold", cl::Hidden, cl::init(false),
static cl::opt<cl::boolOrDefault> AllowTerminatingConditionFoldingAfterLSR(
"lsr-term-fold", cl::Hidden,
cl::desc("Attempt to replace primary IV with other IV."));
static cl::opt<bool> AllowDropSolutionIfLessProfitable(
@@ -6938,7 +6938,18 @@ static bool ReduceLoopStrength(Loop *L, IVUsers &IU, ScalarEvolution &SE,
}
}
if (AllowTerminatingConditionFoldingAfterLSR) {
const bool EnableFormTerm = [&] {
switch (AllowTerminatingConditionFoldingAfterLSR) {
case cl::BOU_TRUE:
return true;
case cl::BOU_FALSE:
return false;
case cl::BOU_UNSET:
return TTI.shouldFoldTerminatingConditionAfterLSR();
}
}();
if (EnableFormTerm) {
if (auto Opt = canFoldTermCondOfLoop(L, SE, DT, LI)) {
auto [ToFold, ToHelpFold, TermValueS, MustDrop] = *Opt;

View File

@@ -120,36 +120,45 @@ define i32 @test_lshr2(ptr nocapture %x, ptr nocapture readonly %y, i32 %n) {
; RV32-LABEL: test_lshr2:
; RV32: # %bb.0: # %entry
; RV32-NEXT: srli a2, a2, 2
; RV32-NEXT: beqz a2, .LBB3_2
; RV32-NEXT: .LBB3_1: # %while.body
; RV32-NEXT: beqz a2, .LBB3_3
; RV32-NEXT: # %bb.1: # %while.body.preheader
; RV32-NEXT: slli a2, a2, 2
; RV32-NEXT: add a2, a1, a2
; RV32-NEXT: .LBB3_2: # %while.body
; RV32-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-NEXT: lw a3, 0(a1)
; RV32-NEXT: addi a1, a1, 4
; RV32-NEXT: addi a4, a1, 4
; RV32-NEXT: slli a3, a3, 1
; RV32-NEXT: addi a4, a0, 4
; RV32-NEXT: addi a2, a2, -1
; RV32-NEXT: addi a1, a0, 4
; RV32-NEXT: sw a3, 0(a0)
; RV32-NEXT: mv a0, a4
; RV32-NEXT: bnez a2, .LBB3_1
; RV32-NEXT: .LBB3_2: # %while.end
; RV32-NEXT: mv a0, a1
; RV32-NEXT: mv a1, a4
; RV32-NEXT: bne a4, a2, .LBB3_2
; RV32-NEXT: .LBB3_3: # %while.end
; RV32-NEXT: li a0, 0
; RV32-NEXT: ret
;
; RV64-LABEL: test_lshr2:
; RV64: # %bb.0: # %entry
; RV64-NEXT: srliw a2, a2, 2
; RV64-NEXT: beqz a2, .LBB3_2
; RV64-NEXT: .LBB3_1: # %while.body
; RV64-NEXT: beqz a2, .LBB3_3
; RV64-NEXT: # %bb.1: # %while.body.preheader
; RV64-NEXT: addi a2, a2, -1
; RV64-NEXT: slli a2, a2, 32
; RV64-NEXT: srli a2, a2, 30
; RV64-NEXT: add a2, a2, a1
; RV64-NEXT: addi a2, a2, 4
; RV64-NEXT: .LBB3_2: # %while.body
; RV64-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-NEXT: lw a3, 0(a1)
; RV64-NEXT: addi a1, a1, 4
; RV64-NEXT: addi a4, a1, 4
; RV64-NEXT: slli a3, a3, 1
; RV64-NEXT: addi a4, a0, 4
; RV64-NEXT: addiw a2, a2, -1
; RV64-NEXT: addi a1, a0, 4
; RV64-NEXT: sw a3, 0(a0)
; RV64-NEXT: mv a0, a4
; RV64-NEXT: bnez a2, .LBB3_1
; RV64-NEXT: .LBB3_2: # %while.end
; RV64-NEXT: mv a0, a1
; RV64-NEXT: mv a1, a4
; RV64-NEXT: bne a4, a2, .LBB3_2
; RV64-NEXT: .LBB3_3: # %while.end
; RV64-NEXT: li a0, 0
; RV64-NEXT: ret
entry:

View File

@@ -8,16 +8,19 @@
define void @test1(ptr nocapture noundef %a, i32 noundef signext %n) {
; CHECK-LABEL: test1:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: blez a1, .LBB0_2
; CHECK-NEXT: .LBB0_1: # %for.body
; CHECK-NEXT: blez a1, .LBB0_3
; CHECK-NEXT: # %bb.1: # %for.body.preheader
; CHECK-NEXT: slli a1, a1, 32
; CHECK-NEXT: srli a1, a1, 30
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: .LBB0_2: # %for.body
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: lw a2, 0(a0)
; CHECK-NEXT: addi a2, a2, 4
; CHECK-NEXT: sw a2, 0(a0)
; CHECK-NEXT: addi a1, a1, -1
; CHECK-NEXT: addi a0, a0, 4
; CHECK-NEXT: bnez a1, .LBB0_1
; CHECK-NEXT: .LBB0_2: # %for.cond.cleanup
; CHECK-NEXT: bne a0, a1, .LBB0_2
; CHECK-NEXT: .LBB0_3: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
%cmp3 = icmp sgt i32 %n, 0

View File

@@ -206,33 +206,19 @@ define <8 x float> @splat_idx_v8f32(<8 x float> %v, i64 %idx) {
; Test that we pull the vlse of the constant pool out of the loop.
define dso_local void @splat_load_licm(float* %0) {
; RV32-LABEL: splat_load_licm:
; RV32: # %bb.0:
; RV32-NEXT: li a1, 1024
; RV32-NEXT: lui a2, 263168
; RV32-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; RV32-NEXT: vmv.v.x v8, a2
; RV32-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1
; RV32-NEXT: vse32.v v8, (a0)
; RV32-NEXT: addi a1, a1, -4
; RV32-NEXT: addi a0, a0, 16
; RV32-NEXT: bnez a1, .LBB12_1
; RV32-NEXT: # %bb.2:
; RV32-NEXT: ret
;
; RV64-LABEL: splat_load_licm:
; RV64: # %bb.0:
; RV64-NEXT: li a1, 1024
; RV64-NEXT: lui a2, 263168
; RV64-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; RV64-NEXT: vmv.v.x v8, a2
; RV64-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1
; RV64-NEXT: vse32.v v8, (a0)
; RV64-NEXT: addiw a1, a1, -4
; RV64-NEXT: addi a0, a0, 16
; RV64-NEXT: bnez a1, .LBB12_1
; RV64-NEXT: # %bb.2:
; RV64-NEXT: ret
; CHECK-LABEL: splat_load_licm:
; CHECK: # %bb.0:
; CHECK-NEXT: lui a1, 1
; CHECK-NEXT: add a1, a0, a1
; CHECK-NEXT: lui a2, 263168
; CHECK-NEXT: vsetivli zero, 4, e32, m1, ta, ma
; CHECK-NEXT: vmv.v.x v8, a2
; CHECK-NEXT: .LBB12_1: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vse32.v v8, (a0)
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: bne a0, a1, .LBB12_1
; CHECK-NEXT: # %bb.2:
; CHECK-NEXT: ret
br label %2
2: ; preds = %2, %1
@@ -1408,3 +1394,6 @@ define <2 x double> @vid_step2_v2f64() {
; CHECK-NEXT: ret
ret <2 x double> <double 0.0, double 2.0>
}
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
; RV32: {{.*}}
; RV64: {{.*}}

View File

@@ -13,7 +13,7 @@
define void @gather(ptr noalias nocapture %A, ptr noalias nocapture readonly %B) {
; CHECK-LABEL: gather:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: addi a2, a0, 1024
; CHECK-NEXT: li a4, 32
; CHECK-NEXT: li a3, 5
; CHECK-NEXT: vsetvli zero, a4, e8, m1, ta, ma
@@ -23,10 +23,9 @@ define void @gather(ptr noalias nocapture %A, ptr noalias nocapture readonly %B)
; CHECK-NEXT: vle8.v v9, (a0)
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: addi a2, a2, -32
; CHECK-NEXT: addi a0, a0, 32
; CHECK-NEXT: addi a1, a1, 160
; CHECK-NEXT: bnez a2, .LBB0_1
; CHECK-NEXT: bne a0, a2, .LBB0_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -54,7 +53,7 @@ for.cond.cleanup: ; preds = %vector.body
define void @gather_masked(ptr noalias nocapture %A, ptr noalias nocapture readonly %B, <32 x i8> %maskedoff) {
; V-LABEL: gather_masked:
; V: # %bb.0: # %entry
; V-NEXT: li a2, 1024
; V-NEXT: addi a2, a0, 1024
; V-NEXT: lui a3, 983765
; V-NEXT: addi a3, a3, 873
; V-NEXT: vsetivli zero, 1, e32, mf2, ta, ma
@@ -69,16 +68,15 @@ define void @gather_masked(ptr noalias nocapture %A, ptr noalias nocapture reado
; V-NEXT: vle8.v v10, (a0)
; V-NEXT: vadd.vv v9, v10, v9
; V-NEXT: vse8.v v9, (a0)
; V-NEXT: addi a2, a2, -32
; V-NEXT: addi a0, a0, 32
; V-NEXT: addi a1, a1, 160
; V-NEXT: bnez a2, .LBB1_1
; V-NEXT: bne a0, a2, .LBB1_1
; V-NEXT: # %bb.2: # %for.cond.cleanup
; V-NEXT: ret
;
; ZVE32F-LABEL: gather_masked:
; ZVE32F: # %bb.0: # %entry
; ZVE32F-NEXT: li a2, 1024
; ZVE32F-NEXT: addi a2, a0, 1024
; ZVE32F-NEXT: lui a3, 983765
; ZVE32F-NEXT: addi a3, a3, 873
; ZVE32F-NEXT: vsetivli zero, 1, e32, m1, ta, ma
@@ -93,10 +91,9 @@ define void @gather_masked(ptr noalias nocapture %A, ptr noalias nocapture reado
; ZVE32F-NEXT: vle8.v v10, (a0)
; ZVE32F-NEXT: vadd.vv v9, v10, v9
; ZVE32F-NEXT: vse8.v v9, (a0)
; ZVE32F-NEXT: addi a2, a2, -32
; ZVE32F-NEXT: addi a0, a0, 32
; ZVE32F-NEXT: addi a1, a1, 160
; ZVE32F-NEXT: bnez a2, .LBB1_1
; ZVE32F-NEXT: bne a0, a2, .LBB1_1
; ZVE32F-NEXT: # %bb.2: # %for.cond.cleanup
; ZVE32F-NEXT: ret
entry:
@@ -125,7 +122,7 @@ define void @gather_negative_stride(ptr noalias nocapture %A, ptr noalias nocapt
; CHECK-LABEL: gather_negative_stride:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi a1, a1, 155
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: addi a2, a0, 1024
; CHECK-NEXT: li a4, 32
; CHECK-NEXT: li a3, -5
; CHECK-NEXT: vsetvli zero, a4, e8, m1, ta, ma
@@ -135,10 +132,9 @@ define void @gather_negative_stride(ptr noalias nocapture %A, ptr noalias nocapt
; CHECK-NEXT: vle8.v v9, (a0)
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: addi a2, a2, -32
; CHECK-NEXT: addi a0, a0, 32
; CHECK-NEXT: addi a1, a1, 160
; CHECK-NEXT: bnez a2, .LBB2_1
; CHECK-NEXT: bne a0, a2, .LBB2_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -166,7 +162,7 @@ for.cond.cleanup: ; preds = %vector.body
define void @gather_zero_stride(ptr noalias nocapture %A, ptr noalias nocapture readonly %B) {
; CHECK-LABEL: gather_zero_stride:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: addi a2, a0, 1024
; CHECK-NEXT: li a3, 32
; CHECK-NEXT: vsetvli zero, a3, e8, m1, ta, ma
; CHECK-NEXT: .LBB3_1: # %vector.body
@@ -175,10 +171,9 @@ define void @gather_zero_stride(ptr noalias nocapture %A, ptr noalias nocapture
; CHECK-NEXT: vle8.v v8, (a0)
; CHECK-NEXT: vadd.vx v8, v8, a3
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: addi a2, a2, -32
; CHECK-NEXT: addi a0, a0, 32
; CHECK-NEXT: addi a1, a1, 160
; CHECK-NEXT: bnez a2, .LBB3_1
; CHECK-NEXT: bne a0, a2, .LBB3_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -206,7 +201,7 @@ for.cond.cleanup: ; preds = %vector.body
define void @gather_zero_stride_unfold(ptr noalias nocapture %A, ptr noalias nocapture readonly %B) {
; V-LABEL: gather_zero_stride_unfold:
; V: # %bb.0: # %entry
; V-NEXT: li a2, 1024
; V-NEXT: addi a2, a0, 1024
; V-NEXT: li a3, 32
; V-NEXT: vsetvli zero, a3, e8, m1, ta, ma
; V-NEXT: .LBB4_1: # %vector.body
@@ -215,16 +210,15 @@ define void @gather_zero_stride_unfold(ptr noalias nocapture %A, ptr noalias noc
; V-NEXT: vle8.v v9, (a0)
; V-NEXT: vdivu.vv v8, v8, v9
; V-NEXT: vse8.v v8, (a0)
; V-NEXT: addi a2, a2, -32
; V-NEXT: addi a0, a0, 32
; V-NEXT: addi a1, a1, 160
; V-NEXT: bnez a2, .LBB4_1
; V-NEXT: bne a0, a2, .LBB4_1
; V-NEXT: # %bb.2: # %for.cond.cleanup
; V-NEXT: ret
;
; ZVE32F-LABEL: gather_zero_stride_unfold:
; ZVE32F: # %bb.0: # %entry
; ZVE32F-NEXT: li a2, 1024
; ZVE32F-NEXT: addi a2, a0, 1024
; ZVE32F-NEXT: li a3, 32
; ZVE32F-NEXT: vsetvli zero, a3, e8, m1, ta, ma
; ZVE32F-NEXT: .LBB4_1: # %vector.body
@@ -233,16 +227,15 @@ define void @gather_zero_stride_unfold(ptr noalias nocapture %A, ptr noalias noc
; ZVE32F-NEXT: vle8.v v9, (a0)
; ZVE32F-NEXT: vdivu.vv v8, v8, v9
; ZVE32F-NEXT: vse8.v v8, (a0)
; ZVE32F-NEXT: addi a2, a2, -32
; ZVE32F-NEXT: addi a0, a0, 32
; ZVE32F-NEXT: addi a1, a1, 160
; ZVE32F-NEXT: bnez a2, .LBB4_1
; ZVE32F-NEXT: bne a0, a2, .LBB4_1
; ZVE32F-NEXT: # %bb.2: # %for.cond.cleanup
; ZVE32F-NEXT: ret
;
; NOT-OPTIMIZED-LABEL: gather_zero_stride_unfold:
; NOT-OPTIMIZED: # %bb.0: # %entry
; NOT-OPTIMIZED-NEXT: li a2, 1024
; NOT-OPTIMIZED-NEXT: addi a2, a0, 1024
; NOT-OPTIMIZED-NEXT: li a3, 32
; NOT-OPTIMIZED-NEXT: vsetvli zero, a3, e8, m1, ta, ma
; NOT-OPTIMIZED-NEXT: .LBB4_1: # %vector.body
@@ -252,10 +245,9 @@ define void @gather_zero_stride_unfold(ptr noalias nocapture %A, ptr noalias noc
; NOT-OPTIMIZED-NEXT: vmv.v.x v9, a3
; NOT-OPTIMIZED-NEXT: vdivu.vv v8, v9, v8
; NOT-OPTIMIZED-NEXT: vse8.v v8, (a0)
; NOT-OPTIMIZED-NEXT: addi a2, a2, -32
; NOT-OPTIMIZED-NEXT: addi a0, a0, 32
; NOT-OPTIMIZED-NEXT: addi a1, a1, 160
; NOT-OPTIMIZED-NEXT: bnez a2, .LBB4_1
; NOT-OPTIMIZED-NEXT: bne a0, a2, .LBB4_1
; NOT-OPTIMIZED-NEXT: # %bb.2: # %for.cond.cleanup
; NOT-OPTIMIZED-NEXT: ret
entry:
@@ -287,7 +279,7 @@ for.cond.cleanup: ; preds = %vector.body
define void @scatter(ptr noalias nocapture %A, ptr noalias nocapture readonly %B) {
; CHECK-LABEL: scatter:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: addi a2, a1, 1024
; CHECK-NEXT: li a4, 32
; CHECK-NEXT: li a3, 5
; CHECK-NEXT: vsetvli zero, a4, e8, m1, ta, ma
@@ -297,10 +289,9 @@ define void @scatter(ptr noalias nocapture %A, ptr noalias nocapture readonly %B
; CHECK-NEXT: vlse8.v v9, (a0), a3
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vsse8.v v8, (a0), a3
; CHECK-NEXT: addi a2, a2, -32
; CHECK-NEXT: addi a1, a1, 32
; CHECK-NEXT: addi a0, a0, 160
; CHECK-NEXT: bnez a2, .LBB5_1
; CHECK-NEXT: bne a1, a2, .LBB5_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -328,7 +319,7 @@ for.cond.cleanup: ; preds = %vector.body
define void @scatter_masked(ptr noalias nocapture %A, ptr noalias nocapture readonly %B, <32 x i8> %maskedoff) {
; V-LABEL: scatter_masked:
; V: # %bb.0: # %entry
; V-NEXT: li a2, 1024
; V-NEXT: addi a2, a1, 1024
; V-NEXT: li a3, 32
; V-NEXT: lui a4, 983765
; V-NEXT: addi a4, a4, 873
@@ -343,16 +334,15 @@ define void @scatter_masked(ptr noalias nocapture %A, ptr noalias nocapture read
; V-NEXT: vlse8.v v10, (a0), a4, v0.t
; V-NEXT: vadd.vv v9, v10, v9
; V-NEXT: vsse8.v v9, (a0), a4, v0.t
; V-NEXT: addi a2, a2, -32
; V-NEXT: addi a1, a1, 32
; V-NEXT: addi a0, a0, 160
; V-NEXT: bnez a2, .LBB6_1
; V-NEXT: bne a1, a2, .LBB6_1
; V-NEXT: # %bb.2: # %for.cond.cleanup
; V-NEXT: ret
;
; ZVE32F-LABEL: scatter_masked:
; ZVE32F: # %bb.0: # %entry
; ZVE32F-NEXT: li a2, 1024
; ZVE32F-NEXT: addi a2, a1, 1024
; ZVE32F-NEXT: li a3, 32
; ZVE32F-NEXT: lui a4, 983765
; ZVE32F-NEXT: addi a4, a4, 873
@@ -367,10 +357,9 @@ define void @scatter_masked(ptr noalias nocapture %A, ptr noalias nocapture read
; ZVE32F-NEXT: vlse8.v v10, (a0), a4, v0.t
; ZVE32F-NEXT: vadd.vv v9, v10, v9
; ZVE32F-NEXT: vsse8.v v9, (a0), a4, v0.t
; ZVE32F-NEXT: addi a2, a2, -32
; ZVE32F-NEXT: addi a1, a1, 32
; ZVE32F-NEXT: addi a0, a0, 160
; ZVE32F-NEXT: bnez a2, .LBB6_1
; ZVE32F-NEXT: bne a1, a2, .LBB6_1
; ZVE32F-NEXT: # %bb.2: # %for.cond.cleanup
; ZVE32F-NEXT: ret
entry:
@@ -402,7 +391,8 @@ for.cond.cleanup: ; preds = %vector.body
define void @gather_pow2(ptr noalias nocapture %A, ptr noalias nocapture readonly %B) {
; CHECK-LABEL: gather_pow2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: lui a2, 1
; CHECK-NEXT: add a2, a0, a2
; CHECK-NEXT: li a3, 16
; CHECK-NEXT: li a4, 32
; CHECK-NEXT: .LBB7_1: # %vector.body
@@ -415,10 +405,9 @@ define void @gather_pow2(ptr noalias nocapture %A, ptr noalias nocapture readonl
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vsetvli zero, a4, e8, m1, ta, ma
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: addi a2, a2, -8
; CHECK-NEXT: addi a0, a0, 32
; CHECK-NEXT: addi a1, a1, 128
; CHECK-NEXT: bnez a2, .LBB7_1
; CHECK-NEXT: bne a0, a2, .LBB7_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -450,7 +439,8 @@ for.cond.cleanup: ; preds = %vector.body
define void @scatter_pow2(ptr noalias nocapture %A, ptr noalias nocapture readonly %B) {
; CHECK-LABEL: scatter_pow2:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: lui a2, 1
; CHECK-NEXT: add a2, a1, a2
; CHECK-NEXT: li a3, 32
; CHECK-NEXT: li a4, 16
; CHECK-NEXT: .LBB8_1: # %vector.body
@@ -461,10 +451,9 @@ define void @scatter_pow2(ptr noalias nocapture %A, ptr noalias nocapture readon
; CHECK-NEXT: vlse32.v v9, (a0), a4
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vsse32.v v8, (a0), a4
; CHECK-NEXT: addi a2, a2, -8
; CHECK-NEXT: addi a1, a1, 32
; CHECK-NEXT: addi a0, a0, 128
; CHECK-NEXT: bnez a2, .LBB8_1
; CHECK-NEXT: bne a1, a2, .LBB8_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -501,7 +490,8 @@ define void @struct_gather(ptr noalias nocapture %A, ptr noalias nocapture reado
; CHECK-LABEL: struct_gather:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: addi a1, a1, 132
; CHECK-NEXT: li a2, 1024
; CHECK-NEXT: lui a2, 1
; CHECK-NEXT: add a2, a0, a2
; CHECK-NEXT: li a3, 16
; CHECK-NEXT: vsetivli zero, 8, e32, m1, ta, ma
; CHECK-NEXT: .LBB9_1: # %vector.body
@@ -516,10 +506,9 @@ define void @struct_gather(ptr noalias nocapture %A, ptr noalias nocapture reado
; CHECK-NEXT: vadd.vv v9, v11, v9
; CHECK-NEXT: vse32.v v8, (a0)
; CHECK-NEXT: vse32.v v9, (a4)
; CHECK-NEXT: addi a2, a2, -16
; CHECK-NEXT: addi a0, a0, 64
; CHECK-NEXT: addi a1, a1, 256
; CHECK-NEXT: bnez a2, .LBB9_1
; CHECK-NEXT: bne a0, a2, .LBB9_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:
@@ -650,7 +639,8 @@ declare void @llvm.masked.scatter.v8i32.v8p0(<8 x i32>, <8 x ptr>, i32 immarg, <
define void @gather_of_pointers(ptr noalias nocapture %arg, ptr noalias nocapture readonly %arg1) {
; V-LABEL: gather_of_pointers:
; V: # %bb.0: # %bb
; V-NEXT: li a2, 1024
; V-NEXT: lui a2, 2
; V-NEXT: add a2, a0, a2
; V-NEXT: li a3, 40
; V-NEXT: vsetivli zero, 2, e64, m1, ta, ma
; V-NEXT: .LBB11_1: # %bb2
@@ -661,22 +651,22 @@ define void @gather_of_pointers(ptr noalias nocapture %arg, ptr noalias nocaptur
; V-NEXT: addi a4, a0, 16
; V-NEXT: vse64.v v8, (a0)
; V-NEXT: vse64.v v9, (a4)
; V-NEXT: addi a2, a2, -4
; V-NEXT: addi a0, a0, 32
; V-NEXT: addi a1, a1, 160
; V-NEXT: bnez a2, .LBB11_1
; V-NEXT: bne a0, a2, .LBB11_1
; V-NEXT: # %bb.2: # %bb18
; V-NEXT: ret
;
; ZVE32F-LABEL: gather_of_pointers:
; ZVE32F: # %bb.0: # %bb
; ZVE32F-NEXT: li a2, 0
; ZVE32F-NEXT: li a3, 1
; ZVE32F-NEXT: li a4, 1024
; ZVE32F-NEXT: lui a3, 2
; ZVE32F-NEXT: add a3, a0, a3
; ZVE32F-NEXT: li a4, 1
; ZVE32F-NEXT: li a5, 40
; ZVE32F-NEXT: .LBB11_1: # %bb2
; ZVE32F-NEXT: # =>This Inner Loop Header: Depth=1
; ZVE32F-NEXT: mul a6, a3, a5
; ZVE32F-NEXT: mul a6, a4, a5
; ZVE32F-NEXT: add a6, a1, a6
; ZVE32F-NEXT: mul a7, a2, a5
; ZVE32F-NEXT: add a7, a1, a7
@@ -689,10 +679,9 @@ define void @gather_of_pointers(ptr noalias nocapture %arg, ptr noalias nocaptur
; ZVE32F-NEXT: sd a6, 24(a0)
; ZVE32F-NEXT: sd a7, 16(a0)
; ZVE32F-NEXT: addi a2, a2, 4
; ZVE32F-NEXT: addi a3, a3, 4
; ZVE32F-NEXT: addi a4, a4, -4
; ZVE32F-NEXT: addi a0, a0, 32
; ZVE32F-NEXT: bnez a4, .LBB11_1
; ZVE32F-NEXT: addi a4, a4, 4
; ZVE32F-NEXT: bne a0, a3, .LBB11_1
; ZVE32F-NEXT: # %bb.2: # %bb18
; ZVE32F-NEXT: ret
bb:
@@ -727,7 +716,8 @@ declare <2 x ptr> @llvm.masked.gather.v2p0.v2p0(<2 x ptr>, i32 immarg, <2 x i1>,
define void @scatter_of_pointers(ptr noalias nocapture %arg, ptr noalias nocapture readonly %arg1) {
; V-LABEL: scatter_of_pointers:
; V: # %bb.0: # %bb
; V-NEXT: li a2, 1024
; V-NEXT: lui a2, 2
; V-NEXT: add a2, a1, a2
; V-NEXT: li a3, 40
; V-NEXT: vsetivli zero, 2, e64, m1, ta, ma
; V-NEXT: .LBB12_1: # %bb2
@@ -738,18 +728,18 @@ define void @scatter_of_pointers(ptr noalias nocapture %arg, ptr noalias nocaptu
; V-NEXT: addi a4, a0, 80
; V-NEXT: vsse64.v v8, (a0), a3
; V-NEXT: vsse64.v v9, (a4), a3
; V-NEXT: addi a2, a2, -4
; V-NEXT: addi a1, a1, 32
; V-NEXT: addi a0, a0, 160
; V-NEXT: bnez a2, .LBB12_1
; V-NEXT: bne a1, a2, .LBB12_1
; V-NEXT: # %bb.2: # %bb18
; V-NEXT: ret
;
; ZVE32F-LABEL: scatter_of_pointers:
; ZVE32F: # %bb.0: # %bb
; ZVE32F-NEXT: li a2, 0
; ZVE32F-NEXT: li a3, 1
; ZVE32F-NEXT: li a4, 1024
; ZVE32F-NEXT: lui a3, 2
; ZVE32F-NEXT: add a3, a1, a3
; ZVE32F-NEXT: li a4, 1
; ZVE32F-NEXT: li a5, 40
; ZVE32F-NEXT: .LBB12_1: # %bb2
; ZVE32F-NEXT: # =>This Inner Loop Header: Depth=1
@@ -757,7 +747,7 @@ define void @scatter_of_pointers(ptr noalias nocapture %arg, ptr noalias nocaptu
; ZVE32F-NEXT: ld a7, 0(a1)
; ZVE32F-NEXT: ld t0, 24(a1)
; ZVE32F-NEXT: ld t1, 16(a1)
; ZVE32F-NEXT: mul t2, a3, a5
; ZVE32F-NEXT: mul t2, a4, a5
; ZVE32F-NEXT: add t2, a0, t2
; ZVE32F-NEXT: mul t3, a2, a5
; ZVE32F-NEXT: add t3, a0, t3
@@ -766,10 +756,9 @@ define void @scatter_of_pointers(ptr noalias nocapture %arg, ptr noalias nocaptu
; ZVE32F-NEXT: sd t1, 80(t3)
; ZVE32F-NEXT: sd t0, 80(t2)
; ZVE32F-NEXT: addi a2, a2, 4
; ZVE32F-NEXT: addi a3, a3, 4
; ZVE32F-NEXT: addi a4, a4, -4
; ZVE32F-NEXT: addi a1, a1, 32
; ZVE32F-NEXT: bnez a4, .LBB12_1
; ZVE32F-NEXT: addi a4, a4, 4
; ZVE32F-NEXT: bne a1, a3, .LBB12_1
; ZVE32F-NEXT: # %bb.2: # %bb18
; ZVE32F-NEXT: ret
bb:
@@ -806,53 +795,56 @@ define void @strided_load_startval_add_with_splat(ptr noalias nocapture %arg, pt
; CHECK-NEXT: li a3, 1024
; CHECK-NEXT: beq a2, a3, .LBB13_7
; CHECK-NEXT: # %bb.1: # %bb3
; CHECK-NEXT: li a4, 1023
; CHECK-NEXT: subw a4, a4, a2
; CHECK-NEXT: li a5, 31
; CHECK-NEXT: mv a3, a2
; CHECK-NEXT: bltu a4, a5, .LBB13_5
; CHECK-NEXT: li a3, 1023
; CHECK-NEXT: subw a5, a3, a2
; CHECK-NEXT: li a6, 31
; CHECK-NEXT: mv a4, a2
; CHECK-NEXT: bltu a5, a6, .LBB13_5
; CHECK-NEXT: # %bb.2: # %bb9
; CHECK-NEXT: slli a4, a4, 32
; CHECK-NEXT: srli a4, a4, 32
; CHECK-NEXT: addi a4, a4, 1
; CHECK-NEXT: andi a5, a4, -32
; CHECK-NEXT: add a3, a5, a2
; CHECK-NEXT: slli a7, a2, 2
; CHECK-NEXT: add a6, a0, a2
; CHECK-NEXT: slli a5, a5, 32
; CHECK-NEXT: srli a5, a5, 32
; CHECK-NEXT: addi a5, a5, 1
; CHECK-NEXT: andi a6, a5, -32
; CHECK-NEXT: add a4, a6, a2
; CHECK-NEXT: slli t0, a2, 2
; CHECK-NEXT: add a7, a0, a2
; CHECK-NEXT: add a2, a1, a2
; CHECK-NEXT: add a2, a2, a7
; CHECK-NEXT: li t0, 32
; CHECK-NEXT: li a7, 5
; CHECK-NEXT: vsetvli zero, t0, e8, m1, ta, ma
; CHECK-NEXT: mv t0, a5
; CHECK-NEXT: add a2, a2, t0
; CHECK-NEXT: add t0, a4, a0
; CHECK-NEXT: li t2, 32
; CHECK-NEXT: li t1, 5
; CHECK-NEXT: vsetvli zero, t2, e8, m1, ta, ma
; CHECK-NEXT: .LBB13_3: # %bb15
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vlse8.v v8, (a2), a7
; CHECK-NEXT: vle8.v v9, (a6)
; CHECK-NEXT: vlse8.v v8, (a2), t1
; CHECK-NEXT: vle8.v v9, (a7)
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vse8.v v8, (a6)
; CHECK-NEXT: addi t0, t0, -32
; CHECK-NEXT: addi a6, a6, 32
; CHECK-NEXT: vse8.v v8, (a7)
; CHECK-NEXT: addi a7, a7, 32
; CHECK-NEXT: addi a2, a2, 160
; CHECK-NEXT: bnez t0, .LBB13_3
; CHECK-NEXT: bne a7, t0, .LBB13_3
; CHECK-NEXT: # %bb.4: # %bb30
; CHECK-NEXT: beq a4, a5, .LBB13_7
; CHECK-NEXT: beq a5, a6, .LBB13_7
; CHECK-NEXT: .LBB13_5: # %bb32
; CHECK-NEXT: addi a2, a3, -1024
; CHECK-NEXT: add a0, a0, a3
; CHECK-NEXT: slli a4, a3, 2
; CHECK-NEXT: add a1, a1, a3
; CHECK-NEXT: add a2, a0, a4
; CHECK-NEXT: slli a5, a4, 2
; CHECK-NEXT: add a1, a1, a4
; CHECK-NEXT: add a1, a1, a5
; CHECK-NEXT: subw a3, a3, a4
; CHECK-NEXT: slli a3, a3, 32
; CHECK-NEXT: srli a3, a3, 32
; CHECK-NEXT: add a0, a4, a0
; CHECK-NEXT: add a0, a0, a3
; CHECK-NEXT: addi a0, a0, 1
; CHECK-NEXT: .LBB13_6: # %bb35
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: lbu a3, 0(a1)
; CHECK-NEXT: lbu a4, 0(a0)
; CHECK-NEXT: lbu a4, 0(a2)
; CHECK-NEXT: add a3, a4, a3
; CHECK-NEXT: sb a3, 0(a0)
; CHECK-NEXT: addiw a2, a2, 1
; CHECK-NEXT: addi a0, a0, 1
; CHECK-NEXT: sb a3, 0(a2)
; CHECK-NEXT: addi a2, a2, 1
; CHECK-NEXT: addi a1, a1, 5
; CHECK-NEXT: bnez a2, .LBB13_6
; CHECK-NEXT: bne a2, a0, .LBB13_6
; CHECK-NEXT: .LBB13_7: # %bb34
; CHECK-NEXT: ret
bb:
@@ -926,6 +918,10 @@ define void @gather_no_scalar_remainder(ptr noalias nocapture noundef %arg, ptr
; CHECK-NEXT: slli a2, a2, 4
; CHECK-NEXT: beqz a2, .LBB14_3
; CHECK-NEXT: # %bb.1: # %bb2
; CHECK-NEXT: addi a2, a2, -16
; CHECK-NEXT: andi a2, a2, -16
; CHECK-NEXT: add a2, a2, a0
; CHECK-NEXT: addi a2, a2, 16
; CHECK-NEXT: li a3, 5
; CHECK-NEXT: vsetivli zero, 16, e8, mf2, ta, ma
; CHECK-NEXT: .LBB14_2: # %bb4
@@ -934,10 +930,9 @@ define void @gather_no_scalar_remainder(ptr noalias nocapture noundef %arg, ptr
; CHECK-NEXT: vle8.v v9, (a0)
; CHECK-NEXT: vadd.vv v8, v9, v8
; CHECK-NEXT: vse8.v v8, (a0)
; CHECK-NEXT: addi a2, a2, -16
; CHECK-NEXT: addi a0, a0, 16
; CHECK-NEXT: addi a1, a1, 80
; CHECK-NEXT: bnez a2, .LBB14_2
; CHECK-NEXT: bne a0, a2, .LBB14_2
; CHECK-NEXT: .LBB14_3: # %bb16
; CHECK-NEXT: ret
bb:

View File

@@ -12,7 +12,7 @@ define void @sink_splat_vp_and_i1(ptr nocapture %a, i1 zeroext %x, <8 x i1> %m,
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vmv.v.x v8, a1
; CHECK-NEXT: vmsne.vi v8, v8, 0
; CHECK-NEXT: li a1, 1024
; CHECK-NEXT: addi a1, a0, 1024
; CHECK-NEXT: .LBB0_1: # %vector.body
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vlm.v v9, (a0)
@@ -20,9 +20,8 @@ define void @sink_splat_vp_and_i1(ptr nocapture %a, i1 zeroext %x, <8 x i1> %m,
; CHECK-NEXT: vmand.mm v9, v9, v8
; CHECK-NEXT: vsetivli zero, 8, e8, mf2, ta, ma
; CHECK-NEXT: vsm.v v9, (a0)
; CHECK-NEXT: addi a1, a1, -1
; CHECK-NEXT: addi a0, a0, 1
; CHECK-NEXT: bnez a1, .LBB0_1
; CHECK-NEXT: bne a0, a1, .LBB0_1
; CHECK-NEXT: # %bb.2: # %for.cond.cleanup
; CHECK-NEXT: ret
entry:

File diff suppressed because it is too large Load Diff

View File

@@ -951,16 +951,15 @@ if.end:
define void @pre_over_vle(ptr %A) {
; CHECK-LABEL: pre_over_vle:
; CHECK: # %bb.0: # %entry
; CHECK-NEXT: li a1, 100
; CHECK-NEXT: addi a1, a0, 800
; CHECK-NEXT: vsetivli zero, 2, e32, mf2, ta, ma
; CHECK-NEXT: .LBB22_1: # %vector.body
; CHECK-NEXT: # =>This Inner Loop Header: Depth=1
; CHECK-NEXT: vle8.v v8, (a0)
; CHECK-NEXT: vsext.vf4 v9, v8
; CHECK-NEXT: vse32.v v9, (a0)
; CHECK-NEXT: addi a1, a1, -1
; CHECK-NEXT: addi a0, a0, 8
; CHECK-NEXT: bnez a1, .LBB22_1
; CHECK-NEXT: bne a0, a1, .LBB22_1
; CHECK-NEXT: # %bb.2: # %exit
; CHECK-NEXT: ret
entry:

View File

@@ -8,15 +8,14 @@ target triple = "riscv64"
define void @test1(ptr %a) {
; CHECK-LABEL: @test1(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 128000
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LOOP]] ], [ [[A]], [[ENTRY:%.*]] ]
; CHECK-NEXT: store float 1.000000e+00, ptr [[LSR_IV1]], align 4
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[SCEVGEP]], [[SCEVGEP2]]
; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
@@ -39,15 +38,14 @@ exit: ; preds = %loop
define void @test2(ptr %a) {
; CHECK-LABEL: @test2(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SCEVGEP2:%.*]] = getelementptr i8, ptr [[A:%.*]], i64 128000
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LOOP]] ], [ [[A]], [[ENTRY:%.*]] ]
; CHECK-NEXT: store float 1.000000e+00, ptr [[LSR_IV1]], align 4
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[SCEVGEP]], [[SCEVGEP2]]
; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: call void @use(ptr [[A]])
; CHECK-NEXT: ret void
@@ -72,19 +70,18 @@ exit: ; preds = %loop
define void @test3(ptr %a, ptr %b) {
; CHECK-LABEL: @test3(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 128000
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi ptr [ [[UGLYGEP3:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[B:%.*]], [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi ptr [ [[SCEVGEP3:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LOOP]] ], [ [[B]], [[ENTRY]] ]
; CHECK-NEXT: [[T17:%.*]] = load float, ptr [[LSR_IV2]], align 4
; CHECK-NEXT: [[T18:%.*]] = fadd float [[T17]], 1.000000e+00
; CHECK-NEXT: store float [[T18]], ptr [[LSR_IV1]], align 4
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[UGLYGEP3]] = getelementptr i8, ptr [[LSR_IV2]], i64 4
; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[SCEVGEP3]] = getelementptr i8, ptr [[LSR_IV2]], i64 4
; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[SCEVGEP]], [[SCEVGEP4]]
; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: ret void
;
@@ -110,19 +107,18 @@ exit: ; preds = %loop
define void @test4(ptr %a, ptr %b) {
; CHECK-LABEL: @test4(
; CHECK-NEXT: entry:
; CHECK-NEXT: [[SCEVGEP4:%.*]] = getelementptr i8, ptr [[B:%.*]], i64 128000
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi ptr [ [[UGLYGEP3:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[UGLYGEP:%.*]], [[LOOP]] ], [ [[B:%.*]], [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV:%.*]] = phi i64 [ [[LSR_IV_NEXT:%.*]], [[LOOP]] ], [ 32000, [[ENTRY]] ]
; CHECK-NEXT: [[LSR_IV2:%.*]] = phi ptr [ [[SCEVGEP3:%.*]], [[LOOP]] ], [ [[A:%.*]], [[ENTRY:%.*]] ]
; CHECK-NEXT: [[LSR_IV1:%.*]] = phi ptr [ [[SCEVGEP:%.*]], [[LOOP]] ], [ [[B]], [[ENTRY]] ]
; CHECK-NEXT: [[T17:%.*]] = load float, ptr [[LSR_IV2]], align 4
; CHECK-NEXT: [[T18:%.*]] = fadd float [[T17]], 1.000000e+00
; CHECK-NEXT: store float [[T18]], ptr [[LSR_IV1]], align 4
; CHECK-NEXT: [[LSR_IV_NEXT]] = add nsw i64 [[LSR_IV]], -1
; CHECK-NEXT: [[UGLYGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[UGLYGEP3]] = getelementptr i8, ptr [[LSR_IV2]], i64 4
; CHECK-NEXT: [[T21:%.*]] = icmp eq i64 [[LSR_IV_NEXT]], 0
; CHECK-NEXT: br i1 [[T21]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK-NEXT: [[SCEVGEP]] = getelementptr i8, ptr [[LSR_IV1]], i64 4
; CHECK-NEXT: [[SCEVGEP3]] = getelementptr i8, ptr [[LSR_IV2]], i64 4
; CHECK-NEXT: [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND:%.*]] = icmp eq ptr [[SCEVGEP]], [[SCEVGEP4]]
; CHECK-NEXT: br i1 [[LSR_FOLD_TERM_COND_REPLACED_TERM_COND]], label [[EXIT:%.*]], label [[LOOP]]
; CHECK: exit:
; CHECK-NEXT: call void @use(ptr [[A]])
; CHECK-NEXT: call void @use(ptr [[B]])