[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:
committed by
Philip Reames
parent
002c54a2e6
commit
e947f95337
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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; }
|
||||
|
||||
@@ -382,6 +382,11 @@ public:
|
||||
return TargetTransformInfoImplBase::isNumRegsMajorCostOfLSR();
|
||||
}
|
||||
|
||||
bool shouldFoldTerminatingConditionAfterLSR() const {
|
||||
return TargetTransformInfoImplBase::
|
||||
shouldFoldTerminatingConditionAfterLSR();
|
||||
}
|
||||
|
||||
bool isProfitableLSRChainElement(Instruction *I) {
|
||||
return TargetTransformInfoImplBase::isProfitableLSRChainElement(I);
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -357,6 +357,10 @@ public:
|
||||
|
||||
bool isLSRCostLess(const TargetTransformInfo::LSRCost &C1,
|
||||
const TargetTransformInfo::LSRCost &C2);
|
||||
|
||||
bool shouldFoldTerminatingConditionAfterLSR() const {
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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: {{.*}}
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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
@@ -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:
|
||||
|
||||
@@ -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]])
|
||||
|
||||
Reference in New Issue
Block a user