Skip to content

Commit a630771

Browse files
authored
[DAG] isConstantIntBuildVectorOrConstantInt - peek through bitcasts (llvm#112710)
Alter both isConstantIntBuildVectorOrConstantInt + isConstantFPBuildVectorOrConstantFP to return a bool instead of the underlying SDNode, and adjust usage to account for this. Update isConstantIntBuildVectorOrConstantInt to peek though bitcasts when attempting to find a constant, in particular this improves canonicalization of constants to the RHS on commutable instructions. X86 is the beneficiary here as it often bitcasts rematerializable 0/-1 vector constants as vXi32 and bitcasts to the requested type Minor cleanup that helps with llvm#107423
1 parent 8f6d491 commit a630771

18 files changed

+570
-650
lines changed

llvm/include/llvm/CodeGen/SelectionDAG.h

+3-2
Original file line numberDiff line numberDiff line change
@@ -2301,10 +2301,11 @@ class SelectionDAG {
23012301
Align getEVTAlign(EVT MemoryVT) const;
23022302

23032303
/// Test whether the given value is a constant int or similar node.
2304-
SDNode *isConstantIntBuildVectorOrConstantInt(SDValue N) const;
2304+
bool isConstantIntBuildVectorOrConstantInt(SDValue N,
2305+
bool AllowOpaques = true) const;
23052306

23062307
/// Test whether the given value is a constant FP or similar node.
2307-
SDNode *isConstantFPBuildVectorOrConstantFP(SDValue N) const ;
2308+
bool isConstantFPBuildVectorOrConstantFP(SDValue N) const;
23082309

23092310
/// \returns true if \p N is any kind of constant or build_vector of
23102311
/// constants, int or float. If a vector, it may not necessarily be a splat.

llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp

+14-20
Original file line numberDiff line numberDiff line change
@@ -1205,13 +1205,13 @@ SDValue DAGCombiner::reassociateOpsCommutative(unsigned Opc, const SDLoc &DL,
12051205
SDValue N00 = N0.getOperand(0);
12061206
SDValue N01 = N0.getOperand(1);
12071207

1208-
if (DAG.isConstantIntBuildVectorOrConstantInt(peekThroughBitcasts(N01))) {
1208+
if (DAG.isConstantIntBuildVectorOrConstantInt(N01)) {
12091209
SDNodeFlags NewFlags;
12101210
if (N0.getOpcode() == ISD::ADD && N0->getFlags().hasNoUnsignedWrap() &&
12111211
Flags.hasNoUnsignedWrap())
12121212
NewFlags.setNoUnsignedWrap(true);
12131213

1214-
if (DAG.isConstantIntBuildVectorOrConstantInt(peekThroughBitcasts(N1))) {
1214+
if (DAG.isConstantIntBuildVectorOrConstantInt(N1)) {
12151215
// Reassociate: (op (op x, c1), c2) -> (op x, (op c1, c2))
12161216
if (SDValue OpNode = DAG.FoldConstantArithmetic(Opc, DL, VT, {N01, N1}))
12171217
return DAG.getNode(Opc, DL, VT, N00, OpNode, NewFlags);
@@ -9931,10 +9931,10 @@ SDValue DAGCombiner::visitRotate(SDNode *N) {
99319931
// fold (rot* (rot* x, c2), c1)
99329932
// -> (rot* x, ((c1 % bitsize) +- (c2 % bitsize) + bitsize) % bitsize)
99339933
if (NextOp == ISD::ROTL || NextOp == ISD::ROTR) {
9934-
SDNode *C1 = DAG.isConstantIntBuildVectorOrConstantInt(N1);
9935-
SDNode *C2 = DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1));
9936-
if (C1 && C2 && C1->getValueType(0) == C2->getValueType(0)) {
9937-
EVT ShiftVT = C1->getValueType(0);
9934+
bool C1 = DAG.isConstantIntBuildVectorOrConstantInt(N1);
9935+
bool C2 = DAG.isConstantIntBuildVectorOrConstantInt(N0.getOperand(1));
9936+
if (C1 && C2 && N1.getValueType() == N0.getOperand(1).getValueType()) {
9937+
EVT ShiftVT = N1.getValueType();
99389938
bool SameSide = (N->getOpcode() == NextOp);
99399939
unsigned CombineOp = SameSide ? ISD::ADD : ISD::SUB;
99409940
SDValue BitsizeC = DAG.getConstant(Bitsize, dl, ShiftVT);
@@ -16805,8 +16805,8 @@ SDValue DAGCombiner::visitVP_FADD(SDNode *N) {
1680516805
SDValue DAGCombiner::visitFADD(SDNode *N) {
1680616806
SDValue N0 = N->getOperand(0);
1680716807
SDValue N1 = N->getOperand(1);
16808-
SDNode *N0CFP = DAG.isConstantFPBuildVectorOrConstantFP(N0);
16809-
SDNode *N1CFP = DAG.isConstantFPBuildVectorOrConstantFP(N1);
16808+
bool N0CFP = DAG.isConstantFPBuildVectorOrConstantFP(N0);
16809+
bool N1CFP = DAG.isConstantFPBuildVectorOrConstantFP(N1);
1681016810
EVT VT = N->getValueType(0);
1681116811
SDLoc DL(N);
1681216812
const TargetOptions &Options = DAG.getTarget().Options;
@@ -16903,10 +16903,8 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
1690316903
// of rounding steps.
1690416904
if (TLI.isOperationLegalOrCustom(ISD::FMUL, VT) && !N0CFP && !N1CFP) {
1690516905
if (N0.getOpcode() == ISD::FMUL) {
16906-
SDNode *CFP00 =
16907-
DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
16908-
SDNode *CFP01 =
16909-
DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1));
16906+
bool CFP00 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
16907+
bool CFP01 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(1));
1691016908

1691116909
// (fadd (fmul x, c), x) -> (fmul x, c+1)
1691216910
if (CFP01 && !CFP00 && N0.getOperand(0) == N1) {
@@ -16926,10 +16924,8 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
1692616924
}
1692716925

1692816926
if (N1.getOpcode() == ISD::FMUL) {
16929-
SDNode *CFP10 =
16930-
DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
16931-
SDNode *CFP11 =
16932-
DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(1));
16927+
bool CFP10 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
16928+
bool CFP11 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(1));
1693316929

1693416930
// (fadd x, (fmul x, c)) -> (fmul x, c+1)
1693516931
if (CFP11 && !CFP10 && N1.getOperand(0) == N0) {
@@ -16949,8 +16945,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
1694916945
}
1695016946

1695116947
if (N0.getOpcode() == ISD::FADD) {
16952-
SDNode *CFP00 =
16953-
DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
16948+
bool CFP00 = DAG.isConstantFPBuildVectorOrConstantFP(N0.getOperand(0));
1695416949
// (fadd (fadd x, x), x) -> (fmul x, 3.0)
1695516950
if (!CFP00 && N0.getOperand(0) == N0.getOperand(1) &&
1695616951
(N0.getOperand(0) == N1)) {
@@ -16960,8 +16955,7 @@ SDValue DAGCombiner::visitFADD(SDNode *N) {
1696016955
}
1696116956

1696216957
if (N1.getOpcode() == ISD::FADD) {
16963-
SDNode *CFP10 =
16964-
DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
16958+
bool CFP10 = DAG.isConstantFPBuildVectorOrConstantFP(N1.getOperand(0));
1696516959
// (fadd x, (fadd x, x)) -> (fmul x, 3.0)
1696616960
if (!CFP10 && N1.getOperand(0) == N1.getOperand(1) &&
1696716961
N1.getOperand(0) == N0) {

llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp

+26-21
Original file line numberDiff line numberDiff line change
@@ -6962,10 +6962,10 @@ void SelectionDAG::canonicalizeCommutativeBinop(unsigned Opcode, SDValue &N1,
69626962

69636963
// Canonicalize:
69646964
// binop(const, nonconst) -> binop(nonconst, const)
6965-
SDNode *N1C = isConstantIntBuildVectorOrConstantInt(N1);
6966-
SDNode *N2C = isConstantIntBuildVectorOrConstantInt(N2);
6967-
SDNode *N1CFP = isConstantFPBuildVectorOrConstantFP(N1);
6968-
SDNode *N2CFP = isConstantFPBuildVectorOrConstantFP(N2);
6965+
bool N1C = isConstantIntBuildVectorOrConstantInt(N1);
6966+
bool N2C = isConstantIntBuildVectorOrConstantInt(N2);
6967+
bool N1CFP = isConstantFPBuildVectorOrConstantFP(N1);
6968+
bool N2CFP = isConstantFPBuildVectorOrConstantFP(N2);
69696969
if ((N1C && !N2C) || (N1CFP && !N2CFP))
69706970
std::swap(N1, N2);
69716971

@@ -13197,39 +13197,44 @@ bool ShuffleVectorSDNode::isSplatMask(const int *Mask, EVT VT) {
1319713197
return true;
1319813198
}
1319913199

13200-
// Returns the SDNode if it is a constant integer BuildVector
13201-
// or constant integer.
13202-
SDNode *SelectionDAG::isConstantIntBuildVectorOrConstantInt(SDValue N) const {
13203-
if (isa<ConstantSDNode>(N))
13204-
return N.getNode();
13200+
// Returns true if it is a constant integer BuildVector or constant integer,
13201+
// possibly hidden by a bitcast.
13202+
bool SelectionDAG::isConstantIntBuildVectorOrConstantInt(
13203+
SDValue N, bool AllowOpaques) const {
13204+
N = peekThroughBitcasts(N);
13205+
13206+
if (auto *C = dyn_cast<ConstantSDNode>(N))
13207+
return AllowOpaques || !C->isOpaque();
13208+
1320513209
if (ISD::isBuildVectorOfConstantSDNodes(N.getNode()))
13206-
return N.getNode();
13210+
return true;
13211+
1320713212
// Treat a GlobalAddress supporting constant offset folding as a
1320813213
// constant integer.
13209-
if (GlobalAddressSDNode *GA = dyn_cast<GlobalAddressSDNode>(N))
13214+
if (auto *GA = dyn_cast<GlobalAddressSDNode>(N))
1321013215
if (GA->getOpcode() == ISD::GlobalAddress &&
1321113216
TLI->isOffsetFoldingLegal(GA))
13212-
return GA;
13217+
return true;
13218+
1321313219
if ((N.getOpcode() == ISD::SPLAT_VECTOR) &&
1321413220
isa<ConstantSDNode>(N.getOperand(0)))
13215-
return N.getNode();
13216-
return nullptr;
13221+
return true;
13222+
return false;
1321713223
}
1321813224

13219-
// Returns the SDNode if it is a constant float BuildVector
13220-
// or constant float.
13221-
SDNode *SelectionDAG::isConstantFPBuildVectorOrConstantFP(SDValue N) const {
13225+
// Returns true if it is a constant float BuildVector or constant float.
13226+
bool SelectionDAG::isConstantFPBuildVectorOrConstantFP(SDValue N) const {
1322213227
if (isa<ConstantFPSDNode>(N))
13223-
return N.getNode();
13228+
return true;
1322413229

1322513230
if (ISD::isBuildVectorOfConstantFPSDNodes(N.getNode()))
13226-
return N.getNode();
13231+
return true;
1322713232

1322813233
if ((N.getOpcode() == ISD::SPLAT_VECTOR) &&
1322913234
isa<ConstantFPSDNode>(N.getOperand(0)))
13230-
return N.getNode();
13235+
return true;
1323113236

13232-
return nullptr;
13237+
return false;
1323313238
}
1323413239

1323513240
std::optional<bool> SelectionDAG::isBoolConstant(SDValue N,

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -20760,7 +20760,7 @@ static SDValue performSubAddMULCombine(SDNode *N, SelectionDAG &DAG) {
2076020760

2076120761
if (!Add.hasOneUse())
2076220762
return SDValue();
20763-
if (DAG.isConstantIntBuildVectorOrConstantInt(peekThroughBitcasts(X)))
20763+
if (DAG.isConstantIntBuildVectorOrConstantInt(X))
2076420764
return SDValue();
2076520765

2076620766
SDValue M1 = Add.getOperand(0);

llvm/lib/Target/X86/X86ISelLowering.cpp

+2-7
Original file line numberDiff line numberDiff line change
@@ -56543,14 +56543,9 @@ static SDValue combineSub(SDNode *N, SelectionDAG &DAG,
5654356543
SDValue Op1 = N->getOperand(1);
5654456544
SDLoc DL(N);
5654556545

56546-
// TODO: Add NoOpaque handling to isConstantIntBuildVectorOrConstantInt.
5654756546
auto IsNonOpaqueConstant = [&](SDValue Op) {
56548-
if (SDNode *C = DAG.isConstantIntBuildVectorOrConstantInt(Op)) {
56549-
if (auto *Cst = dyn_cast<ConstantSDNode>(C))
56550-
return !Cst->isOpaque();
56551-
return true;
56552-
}
56553-
return false;
56547+
return DAG.isConstantIntBuildVectorOrConstantInt(Op,
56548+
/*AllowOpaques*/ false);
5655456549
};
5655556550

5655656551
// X86 can't encode an immediate LHS of a sub. See if we can push the

llvm/test/CodeGen/X86/avx2-arith.ll

+1-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,7 @@ define <32 x i8> @mul_v32i8(<32 x i8> %i, <32 x i8> %j) nounwind readnone {
122122
; CHECK-LABEL: mul_v32i8:
123123
; CHECK: # %bb.0:
124124
; CHECK-NEXT: vpbroadcastw {{.*#+}} ymm2 = [255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255]
125-
; CHECK-NEXT: vpand %ymm1, %ymm2, %ymm3
125+
; CHECK-NEXT: vpand %ymm2, %ymm1, %ymm3
126126
; CHECK-NEXT: vpmaddubsw %ymm3, %ymm0, %ymm3
127127
; CHECK-NEXT: vpand %ymm2, %ymm3, %ymm3
128128
; CHECK-NEXT: vpandn %ymm1, %ymm2, %ymm1

llvm/test/CodeGen/X86/combine-sra.ll

+4-5
Original file line numberDiff line numberDiff line change
@@ -725,12 +725,11 @@ define <4 x i64> @combine_vec4i64_ashr_clamped(<4 x i64> %x, <4 x i64> %y) {
725725
; SSE41: # %bb.0:
726726
; SSE41-NEXT: movdqa %xmm0, %xmm4
727727
; SSE41-NEXT: movdqa {{.*#+}} xmm7 = [9223372039002259456,9223372039002259456]
728-
; SSE41-NEXT: movdqa %xmm3, %xmm0
729-
; SSE41-NEXT: pxor %xmm7, %xmm0
728+
; SSE41-NEXT: movdqa %xmm3, %xmm6
729+
; SSE41-NEXT: pxor %xmm7, %xmm6
730730
; SSE41-NEXT: movdqa {{.*#+}} xmm8 = [9223372039002259519,9223372039002259519]
731-
; SSE41-NEXT: movdqa %xmm8, %xmm6
732-
; SSE41-NEXT: pcmpeqd %xmm0, %xmm6
733-
; SSE41-NEXT: pshufd {{.*#+}} xmm9 = xmm0[0,0,2,2]
731+
; SSE41-NEXT: pshufd {{.*#+}} xmm9 = xmm6[0,0,2,2]
732+
; SSE41-NEXT: pcmpeqd %xmm8, %xmm6
734733
; SSE41-NEXT: movdqa {{.*#+}} xmm5 = [2147483711,2147483711,2147483711,2147483711]
735734
; SSE41-NEXT: movdqa %xmm5, %xmm0
736735
; SSE41-NEXT: pcmpgtd %xmm9, %xmm0

0 commit comments

Comments
 (0)