Skip to content

Commit dbbfc95

Browse files
authored
[RISCV] Separate ActiveElementsAffectResult into VL and Mask flags (#106517)
In #106110 we had to mark v[f]slide1down.vx as ActiveElementsAffectResult since the elements in the body depend on VL. However it doesn't depend on the mask, so this was overly conservative and broke the vmerge peephole. We can recover this by splitting up ActiveElementsAffectResult into VL and Mask bits, so we can more accurately model v[f]slide1down.vx and re-enable the peephole.
1 parent 9df92cb commit dbbfc95

File tree

9 files changed

+62
-43
lines changed

9 files changed

+62
-43
lines changed

llvm/lib/Target/RISCV/MCTargetDesc/RISCVBaseInfo.h

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,11 @@ enum {
124124
TargetOverlapConstraintTypeShift = UsesVXRMShift + 1,
125125
TargetOverlapConstraintTypeMask = 3ULL << TargetOverlapConstraintTypeShift,
126126

127-
ActiveElementsAffectResultShift = TargetOverlapConstraintTypeShift + 2,
128-
ActiveElementsAffectResultMask = 1ULL << ActiveElementsAffectResultShift,
127+
ElementsDependOnVLShift = TargetOverlapConstraintTypeShift + 2,
128+
ElementsDependOnVLMask = 1ULL << ElementsDependOnVLShift,
129+
130+
ElementsDependOnMaskShift = ElementsDependOnVLShift + 1,
131+
ElementsDependOnMaskMask = 1ULL << ElementsDependOnMaskShift,
129132
};
130133

131134
// Helper functions to read TSFlags.
@@ -174,10 +177,16 @@ static inline bool hasRoundModeOp(uint64_t TSFlags) {
174177
/// \returns true if this instruction uses vxrm
175178
static inline bool usesVXRM(uint64_t TSFlags) { return TSFlags & UsesVXRMMask; }
176179

177-
/// \returns true if the result isn't element-wise,
178-
/// e.g. vredsum.vs/vcompress.vm/viota.m
179-
static inline bool activeElementsAffectResult(uint64_t TSFlags) {
180-
return TSFlags & ActiveElementsAffectResultMask;
180+
/// \returns true if the elements in the body are affected by VL,
181+
/// e.g. vslide1down.vx/vredsum.vs/viota.m
182+
static inline bool elementsDependOnVL(uint64_t TSFlags) {
183+
return TSFlags & ElementsDependOnVLMask;
184+
}
185+
186+
/// \returns true if the elements in the body are affected by the mask,
187+
/// e.g. vredsum.vs/viota.m
188+
static inline bool elementsDependOnMask(uint64_t TSFlags) {
189+
return TSFlags & ElementsDependOnMaskMask;
181190
}
182191

183192
static inline unsigned getVLOpNum(const MCInstrDesc &Desc) {

llvm/lib/Target/RISCV/RISCVISelDAGToDAG.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3941,12 +3941,11 @@ bool RISCVDAGToDAGISel::performCombineVMergeAndVOps(SDNode *N) {
39413941
// active elements, like viota.m or vredsum. This transformation is illegal
39423942
// for these if we change the active elements (i.e. mask or VL).
39433943
const MCInstrDesc &TrueBaseMCID = TII->get(RISCV::getRVVMCOpcode(TrueOpc));
3944-
if (RISCVII::activeElementsAffectResult(TrueBaseMCID.TSFlags)) {
3945-
if (Mask && !usesAllOnesMask(Mask, Glue))
3946-
return false;
3947-
if (TrueVL != VL)
3948-
return false;
3949-
}
3944+
if (RISCVII::elementsDependOnVL(TrueBaseMCID.TSFlags) && (TrueVL != VL))
3945+
return false;
3946+
if (RISCVII::elementsDependOnMask(TrueBaseMCID.TSFlags) &&
3947+
(Mask && !usesAllOnesMask(Mask, Glue)))
3948+
return false;
39503949

39513950
// If we end up changing the VL or mask of True, then we need to make sure it
39523951
// doesn't raise any observable fp exceptions, since changing the active

llvm/lib/Target/RISCV/RISCVInstrFormats.td

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,15 @@ def OPC_SYSTEM : RISCVOpcode<"SYSTEM", 0b1110011>;
158158
def OPC_OP_VE : RISCVOpcode<"OP_VE", 0b1110111>;
159159
def OPC_CUSTOM_3 : RISCVOpcode<"CUSTOM_3", 0b1111011>;
160160

161+
class EltDeps<bit vl, bit mask> {
162+
bit VL = vl;
163+
bit Mask = mask;
164+
}
165+
166+
def EltDepsNone : EltDeps<vl=0, mask=0>;
167+
def EltDepsVL : EltDeps<vl=1, mask=0>;
168+
def EltDepsVLMask : EltDeps<vl=1, mask=1>;
169+
161170
class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
162171
list<dag> pattern, InstFormat format> : Instruction {
163172
let Namespace = "RISCV";
@@ -224,8 +233,13 @@ class RVInstCommon<dag outs, dag ins, string opcodestr, string argstr,
224233
bits<2> TargetOverlapConstraintType = 0;
225234
let TSFlags{22-21} = TargetOverlapConstraintType;
226235

227-
bit ActiveElementsAffectResult = 0;
228-
let TSFlags{23} = ActiveElementsAffectResult;
236+
// Most vector instructions are elementwise, but some may depend on the value
237+
// of VL (e.g. vslide1down.vx), and others may depend on the VL and mask
238+
// (e.g. vredsum.vs, viota.m). Mark these instructions so that peepholes avoid
239+
// changing their VL and/or mask.
240+
EltDeps ElementsDependOn = EltDepsNone;
241+
let TSFlags{23} = ElementsDependOn.VL;
242+
let TSFlags{24} = ElementsDependOn.Mask;
229243
}
230244

231245
class RVInst<dag outs, dag ins, string opcodestr, string argstr,

llvm/lib/Target/RISCV/RISCVInstrInfoV.td

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1503,7 +1503,7 @@ defm VFNCVT_ROD_F_F_W : VNCVTF_FV_VS2<"vfncvt.rod.f.f.w", 0b010010, 0b10101>;
15031503
let Predicates = [HasVInstructions] in {
15041504

15051505
// Vector Single-Width Integer Reduction Instructions
1506-
let RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1 in {
1506+
let RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {
15071507
defm VREDSUM : VRED_MV_V<"vredsum", 0b000000>;
15081508
defm VREDMAXU : VREDMINMAX_MV_V<"vredmaxu", 0b000110>;
15091509
defm VREDMAX : VREDMINMAX_MV_V<"vredmax", 0b000111>;
@@ -1512,23 +1512,23 @@ defm VREDMIN : VREDMINMAX_MV_V<"vredmin", 0b000101>;
15121512
defm VREDAND : VRED_MV_V<"vredand", 0b000001>;
15131513
defm VREDOR : VRED_MV_V<"vredor", 0b000010>;
15141514
defm VREDXOR : VRED_MV_V<"vredxor", 0b000011>;
1515-
} // RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1
1515+
} // RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask
15161516

15171517
// Vector Widening Integer Reduction Instructions
1518-
let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1 in {
1518+
let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {
15191519
// Set earlyclobber for following instructions for second and mask operands.
15201520
// This has the downside that the earlyclobber constraint is too coarse and
15211521
// will impose unnecessary restrictions by not allowing the destination to
15221522
// overlap with the first (wide) operand.
15231523
defm VWREDSUMU : VWRED_IV_V<"vwredsumu", 0b110000>;
15241524
defm VWREDSUM : VWRED_IV_V<"vwredsum", 0b110001>;
1525-
} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1
1525+
} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask
15261526

15271527
} // Predicates = [HasVInstructions]
15281528

15291529
let Predicates = [HasVInstructionsAnyF] in {
15301530
// Vector Single-Width Floating-Point Reduction Instructions
1531-
let RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1 in {
1531+
let RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {
15321532
let Uses = [FRM], mayRaiseFPException = true in {
15331533
defm VFREDOSUM : VREDO_FV_V<"vfredosum", 0b000011>;
15341534
defm VFREDUSUM : VRED_FV_V<"vfredusum", 0b000001>;
@@ -1537,13 +1537,13 @@ let mayRaiseFPException = true in {
15371537
defm VFREDMAX : VREDMINMAX_FV_V<"vfredmax", 0b000111>;
15381538
defm VFREDMIN : VREDMINMAX_FV_V<"vfredmin", 0b000101>;
15391539
}
1540-
} // RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1
1540+
} // RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask
15411541

15421542
def : InstAlias<"vfredsum.vs $vd, $vs2, $vs1$vm",
15431543
(VFREDUSUM_VS VR:$vd, VR:$vs2, VR:$vs1, VMaskOp:$vm), 0>;
15441544

15451545
// Vector Widening Floating-Point Reduction Instructions
1546-
let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1 in {
1546+
let Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {
15471547
// Set earlyclobber for following instructions for second and mask operands.
15481548
// This has the downside that the earlyclobber constraint is too coarse and
15491549
// will impose unnecessary restrictions by not allowing the destination to
@@ -1552,7 +1552,7 @@ let Uses = [FRM], mayRaiseFPException = true in {
15521552
defm VFWREDOSUM : VWREDO_FV_V<"vfwredosum", 0b110011>;
15531553
defm VFWREDUSUM : VWRED_FV_V<"vfwredusum", 0b110001>;
15541554
}
1555-
} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1
1555+
} // Constraints = "@earlyclobber $vd", RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask
15561556

15571557
def : InstAlias<"vfwredsum.vs $vd, $vs2, $vs1$vm",
15581558
(VFWREDUSUM_VS VR:$vd, VR:$vs2, VR:$vs1, VMaskOp:$vm), 0>;
@@ -1586,7 +1586,7 @@ def : InstAlias<"vmornot.mm $vd, $vs2, $vs1",
15861586
(VMORN_MM VR:$vd, VR:$vs2, VR:$vs1), 0>;
15871587

15881588
let hasSideEffects = 0, mayLoad = 0, mayStore = 0,
1589-
RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1 in {
1589+
RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask in {
15901590

15911591
// Vector mask population count vcpop
15921592
def VCPOP_M : RVInstV<0b010000, 0b10000, OPMVV, (outs GPR:$vd),
@@ -1600,12 +1600,12 @@ def VFIRST_M : RVInstV<0b010000, 0b10001, OPMVV, (outs GPR:$vd),
16001600
"vfirst.m", "$vd, $vs2$vm">,
16011601
SchedUnaryMC<"WriteVMFFSV", "ReadVMFFSV">;
16021602

1603-
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, RVVConstraint = NoConstraint, ActiveElementsAffectResult = 1
1603+
} // hasSideEffects = 0, mayLoad = 0, mayStore = 0, RVVConstraint = NoConstraint, ElementsDependOn = EltDepsVLMask
16041604

16051605
def : InstAlias<"vpopc.m $vd, $vs2$vm",
16061606
(VCPOP_M GPR:$vd, VR:$vs2, VMaskOp:$vm), 0>;
16071607

1608-
let Constraints = "@earlyclobber $vd", RVVConstraint = Iota, ActiveElementsAffectResult = 1 in {
1608+
let Constraints = "@earlyclobber $vd", RVVConstraint = Iota, ElementsDependOn = EltDepsVLMask in {
16091609

16101610
// vmsbf.m set-before-first mask bit
16111611
defm VMSBF_M : VMSFS_MV_V<"vmsbf.m", 0b010100, 0b00001>;
@@ -1616,7 +1616,7 @@ defm VMSOF_M : VMSFS_MV_V<"vmsof.m", 0b010100, 0b00010>;
16161616
// Vector Iota Instruction
16171617
defm VIOTA_M : VIOTA_MV_V<"viota.m", 0b010100, 0b10000>;
16181618

1619-
} // Constraints = "@earlyclobber $vd", RVVConstraint = Iota, ActiveElementsAffectResult = 1
1619+
} // Constraints = "@earlyclobber $vd", RVVConstraint = Iota, ElementsDependOn = EltDepsVLMask
16201620

16211621
// Vector Element Index Instruction
16221622
let hasSideEffects = 0, mayLoad = 0, mayStore = 0 in {
@@ -1665,15 +1665,15 @@ defm VSLIDEUP_V : VSLD_IV_X_I<"vslideup", 0b001110, /*slidesUp=*/true>;
16651665
defm VSLIDE1UP_V : VSLD1_MV_X<"vslide1up", 0b001110>;
16661666
} // Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp
16671667
defm VSLIDEDOWN_V : VSLD_IV_X_I<"vslidedown", 0b001111, /*slidesUp=*/false>;
1668-
let ActiveElementsAffectResult = 1 in
1668+
let ElementsDependOn = EltDepsVL in
16691669
defm VSLIDE1DOWN_V : VSLD1_MV_X<"vslide1down", 0b001111>;
16701670
} // Predicates = [HasVInstructions]
16711671

16721672
let Predicates = [HasVInstructionsAnyF] in {
16731673
let Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp in {
16741674
defm VFSLIDE1UP_V : VSLD1_FV_F<"vfslide1up", 0b001110>;
16751675
} // Constraints = "@earlyclobber $vd", RVVConstraint = SlideUp
1676-
let ActiveElementsAffectResult = 1 in
1676+
let ElementsDependOn = EltDepsVL in
16771677
defm VFSLIDE1DOWN_V : VSLD1_FV_F<"vfslide1down", 0b001111>;
16781678
} // Predicates = [HasVInstructionsAnyF]
16791679

@@ -1688,9 +1688,9 @@ def VRGATHEREI16_VV : VALUVV<0b001110, OPIVV, "vrgatherei16.vv">,
16881688
} // Constraints = "@earlyclobber $vd", RVVConstraint = Vrgather
16891689

16901690
// Vector Compress Instruction
1691-
let Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress, ActiveElementsAffectResult = 1 in {
1691+
let Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress, ElementsDependOn = EltDepsVLMask in {
16921692
defm VCOMPRESS_V : VCPR_MV_Mask<"vcompress", 0b010111>;
1693-
} // Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress, ActiveElementsAffectResult = 1
1693+
} // Constraints = "@earlyclobber $vd", RVVConstraint = Vcompress, ElementsDependOn = EltDepsVLMask
16941694

16951695
let hasSideEffects = 0, mayLoad = 0, mayStore = 0, isMoveReg = 1,
16961696
RVVConstraint = NoConstraint in {

llvm/lib/Target/RISCV/RISCVInstrInfoXSf.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ class RVInstVCCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
7575

7676
let Uses = [VTYPE, VL];
7777
let RVVConstraint = NoConstraint;
78-
let ActiveElementsAffectResult = 1;
78+
let ElementsDependOn = EltDepsVLMask;
7979
}
8080

8181
class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
@@ -99,7 +99,7 @@ class RVInstVCFCustom2<bits<4> funct6_hi4, bits<3> funct3, dag outs, dag ins,
9999

100100
let Uses = [VTYPE, VL];
101101
let RVVConstraint = NoConstraint;
102-
let ActiveElementsAffectResult = 1;
102+
let ElementsDependOn = EltDepsVLMask;
103103
}
104104

105105
class VCIXInfo<string suffix, VCIXType type, DAGOperand TyRd,

llvm/lib/Target/RISCV/RISCVInstrInfoXTHead.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,13 @@ class THStoreUpdate<bits<5> funct5, string opcodestr>
235235
//===----------------------------------------------------------------------===//
236236

237237
multiclass THVdotVMAQA_VX<string opcodestr, bits<6> funct6> {
238-
let RVVConstraint = WidenV, ActiveElementsAffectResult = 1 in
238+
let RVVConstraint = WidenV, ElementsDependOn = EltDepsVLMask in
239239
def _VX : THVdotALUrVX<funct6, OPMVX, opcodestr # ".vx", EarlyClobber=1>;
240240
}
241241

242242
multiclass THVdotVMAQA<string opcodestr, bits<6> funct6>
243243
: THVdotVMAQA_VX<opcodestr, funct6> {
244-
let RVVConstraint = WidenV, ActiveElementsAffectResult = 1 in
244+
let RVVConstraint = WidenV, ElementsDependOn = EltDepsVLMask in
245245
def _VV : THVdotALUrVV<funct6, OPMVX, opcodestr # ".vv", EarlyClobber=1>;
246246
}
247247

llvm/lib/Target/RISCV/RISCVInstrInfoZvk.td

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -140,7 +140,7 @@ let Predicates = [HasStdExtZvkb] in {
140140
defm VROR_V : VROR_IV_V_X_I<"vror", 0b010100>;
141141
} // Predicates = [HasStdExtZvkb]
142142

143-
let ActiveElementsAffectResult = 1 in {
143+
let ElementsDependOn = EltDepsVLMask in {
144144

145145
let Predicates = [HasStdExtZvkg], RVVConstraint = NoConstraint in {
146146
def VGHSH_VV : PALUVVNoVmTernary<0b101100, OPMVV, "vghsh.vv">,
@@ -198,7 +198,7 @@ let Predicates = [HasStdExtZvksh], RVVConstraint = VS2Constraint in {
198198
SchedUnaryMC<"WriteVSM3MEV", "ReadVSM3MEV">;
199199
} // Predicates = [HasStdExtZvksh]
200200

201-
} // ActiveElementsAffectResult = 1
201+
} // ElementsDependOn = EltDepsVLMask
202202

203203
//===----------------------------------------------------------------------===//
204204
// Pseudo instructions

llvm/lib/Target/RISCV/RISCVVectorPeephole.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -156,9 +156,9 @@ bool RISCVVectorPeephole::tryToReduceVL(MachineInstr &MI) const {
156156
if (getSEWLMULRatio(MI) != getSEWLMULRatio(*Src))
157157
return false;
158158

159-
bool ActiveElementsAffectResult = RISCVII::activeElementsAffectResult(
159+
bool ElementsDependOnVL = RISCVII::elementsDependOnVL(
160160
TII->get(RISCV::getRVVMCOpcode(Src->getOpcode())).TSFlags);
161-
if (ActiveElementsAffectResult || Src->mayRaiseFPException())
161+
if (ElementsDependOnVL || Src->mayRaiseFPException())
162162
return false;
163163

164164
MachineOperand &SrcVL = Src->getOperand(RISCVII::getVLOpNum(Src->getDesc()));

llvm/test/CodeGen/RISCV/rvv/rvv-peephole-vmerge-vops.ll

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -776,15 +776,12 @@ define <vscale x 2 x i32> @vpselect_vslide1up(<vscale x 2 x i32> %passthru, <vsc
776776
ret <vscale x 2 x i32> %b
777777
}
778778

779-
; FIXME: We can still fold this given that the vmerge and the vslide1down have
780-
; the same vl.
781779
declare <vscale x 2 x i32> @llvm.riscv.vslide1down.nxv2i32.i32(<vscale x 2 x i32>, <vscale x 2 x i32>, i32, i64)
782780
define <vscale x 2 x i32> @vpselect_vslide1down(<vscale x 2 x i32> %passthru, <vscale x 2 x i32> %v, i32 %x, <vscale x 2 x i1> %m, i32 zeroext %vl) {
783781
; CHECK-LABEL: vpselect_vslide1down:
784782
; CHECK: # %bb.0:
785-
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, ma
786-
; CHECK-NEXT: vslide1down.vx v9, v9, a0
787-
; CHECK-NEXT: vmerge.vvm v8, v8, v9, v0
783+
; CHECK-NEXT: vsetvli zero, a1, e32, m1, ta, mu
784+
; CHECK-NEXT: vslide1down.vx v8, v9, a0, v0.t
788785
; CHECK-NEXT: ret
789786
%1 = zext i32 %vl to i64
790787
%a = call <vscale x 2 x i32> @llvm.riscv.vslide1down.nxv2i32.i32(<vscale x 2 x i32> undef, <vscale x 2 x i32> %v, i32 %x, i64 %1)

0 commit comments

Comments
 (0)