Skip to content

Commit 9f215be

Browse files
committed
[DAGCombiner][RISCV] Add target hook to decide hoisting LogicOp with extension.
This patch introduces a new target hook `isDesirableToHoistLogicOpWithExt` to allow target to decide hoisting LogicOp where both operands have the same extension op. By default it returns true. On RISC-V, (or disjoint (sext/zext a), (sext/zext b)) can be combined as vwadd.vv/vwaddu.vv. So for such case, it returns false.
1 parent 497382e commit 9f215be

File tree

5 files changed

+28
-10
lines changed

5 files changed

+28
-10
lines changed

llvm/include/llvm/CodeGen/TargetLowering.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4462,6 +4462,16 @@ class TargetLowering : public TargetLoweringBase {
44624462
return false;
44634463
}
44644464

4465+
/// Return true if it is profitable to hoist a LogicOp where both operands
4466+
/// have the same extension op. This transformation may not be desirable if
4467+
/// it disrupts a particularly auspicious target-specific tree (e.g.
4468+
/// (or disjoint (zext A), (zext B)) -> vwaddu.wv on RISC-V). By default it
4469+
/// returns true.
4470+
virtual bool isDesirableToHoistLogicOpWithExt(const SDNode *LogicOp,
4471+
unsigned ExtOp) const {
4472+
return true;
4473+
}
4474+
44654475
/// Return true if the target supports swifterror attribute. It optimizes
44664476
/// loads and stores to reading and writing a specific register.
44674477
virtual bool supportSwiftError() const {

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5981,6 +5981,9 @@ SDValue DAGCombiner::hoistLogicOpWithSameOpcodeHands(SDNode *N) {
59815981
HandOpcode == ISD::ANY_EXTEND_VECTOR_INREG) &&
59825982
LegalTypes && !TLI.isTypeDesirableForOp(LogicOpcode, XVT))
59835983
return SDValue();
5984+
// If it is not desirable to hoist LogicOp with extension.
5985+
if (!TLI.isDesirableToHoistLogicOpWithExt(N, HandOpcode))
5986+
return SDValue();
59845987
// logic_op (hand_op X), (hand_op Y) --> hand_op (logic_op X, Y)
59855988
SDValue Logic = DAG.getNode(LogicOpcode, DL, XVT, X, Y);
59865989
if (HandOpcode == ISD::SIGN_EXTEND_INREG)

llvm/lib/Target/RISCV/RISCVISelLowering.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19893,6 +19893,14 @@ bool RISCVTargetLowering::isDesirableToCommuteWithShift(
1989319893
return true;
1989419894
}
1989519895

19896+
bool RISCVTargetLowering::isDesirableToHoistLogicOpWithExt(
19897+
const SDNode *LogicOp, unsigned ExtOp) const {
19898+
if (NodeExtensionHelper::isSupportedRoot(LogicOp, Subtarget) &&
19899+
(ExtOp == ISD::ZERO_EXTEND || ExtOp == ISD::SIGN_EXTEND))
19900+
return false;
19901+
return true;
19902+
}
19903+
1989619904
bool RISCVTargetLowering::targetShrinkDemandedConstant(
1989719905
SDValue Op, const APInt &DemandedBits, const APInt &DemandedElts,
1989819906
TargetLoweringOpt &TLO) const {

llvm/lib/Target/RISCV/RISCVISelLowering.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -747,6 +747,9 @@ class RISCVTargetLowering : public TargetLowering {
747747
bool isDesirableToCommuteWithShift(const SDNode *N,
748748
CombineLevel Level) const override;
749749

750+
bool isDesirableToHoistLogicOpWithExt(const SDNode *LogicOp,
751+
unsigned ExtOp) const override;
752+
750753
/// If a physical register, this returns the register that receives the
751754
/// exception address on entry to an EH pad.
752755
Register

llvm/test/CodeGen/RISCV/rvv/vwadd-sdnode.ll

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1417,31 +1417,25 @@ define <vscale x 2 x i32> @vwaddu_vv_disjoint_or_add(<vscale x 2 x i8> %x.i8, <v
14171417
ret <vscale x 2 x i32> %add
14181418
}
14191419

1420-
; TODO: We could select vwaddu.vv, but when both arms of the or are the same
1421-
; DAGCombiner::hoistLogicOpWithSameOpcodeHands moves the zext above the or.
14221420
define <vscale x 2 x i32> @vwaddu_vv_disjoint_or(<vscale x 2 x i16> %x.i16, <vscale x 2 x i16> %y.i16) {
14231421
; CHECK-LABEL: vwaddu_vv_disjoint_or:
14241422
; CHECK: # %bb.0:
14251423
; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
1426-
; CHECK-NEXT: vor.vv v9, v8, v9
1427-
; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma
1428-
; CHECK-NEXT: vzext.vf2 v8, v9
1424+
; CHECK-NEXT: vwaddu.vv v10, v8, v9
1425+
; CHECK-NEXT: vmv1r.v v8, v10
14291426
; CHECK-NEXT: ret
14301427
%x.i32 = zext <vscale x 2 x i16> %x.i16 to <vscale x 2 x i32>
14311428
%y.i32 = zext <vscale x 2 x i16> %y.i16 to <vscale x 2 x i32>
14321429
%or = or disjoint <vscale x 2 x i32> %x.i32, %y.i32
14331430
ret <vscale x 2 x i32> %or
14341431
}
14351432

1436-
; TODO: We could select vwadd.vv, but when both arms of the or are the same
1437-
; DAGCombiner::hoistLogicOpWithSameOpcodeHands moves the zext above the or.
14381433
define <vscale x 2 x i32> @vwadd_vv_disjoint_or(<vscale x 2 x i16> %x.i16, <vscale x 2 x i16> %y.i16) {
14391434
; CHECK-LABEL: vwadd_vv_disjoint_or:
14401435
; CHECK: # %bb.0:
14411436
; CHECK-NEXT: vsetvli a0, zero, e16, mf2, ta, ma
1442-
; CHECK-NEXT: vor.vv v9, v8, v9
1443-
; CHECK-NEXT: vsetvli zero, zero, e32, m1, ta, ma
1444-
; CHECK-NEXT: vsext.vf2 v8, v9
1437+
; CHECK-NEXT: vwadd.vv v10, v8, v9
1438+
; CHECK-NEXT: vmv1r.v v8, v10
14451439
; CHECK-NEXT: ret
14461440
%x.i32 = sext <vscale x 2 x i16> %x.i16 to <vscale x 2 x i32>
14471441
%y.i32 = sext <vscale x 2 x i16> %y.i16 to <vscale x 2 x i32>

0 commit comments

Comments
 (0)