Skip to content

Commit bc94fa5

Browse files
Implement AND_NOT for AAarch
1 parent 3a7abbd commit bc94fa5

File tree

10 files changed

+106
-8
lines changed

10 files changed

+106
-8
lines changed

src/coreclr/jit/codegenarm.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,8 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
306306
var_types targetType = treeNode->TypeGet();
307307
emitter* emit = GetEmitter();
308308

309-
assert(oper == GT_ADD || oper == GT_SUB || oper == GT_MUL || oper == GT_ADD_LO || oper == GT_ADD_HI ||
310-
oper == GT_SUB_LO || oper == GT_SUB_HI || oper == GT_OR || oper == GT_XOR || oper == GT_AND);
309+
assert(treeNode->OperIs(GT_ADD, GT_SUB, GT_MUL, GT_ADD_LO, GT_ADD_HI, GT_SUB_LO, GT_SUB_HI, GT_OR, GT_XOR, GT_AND,
310+
GT_AND_NOT));
311311

312312
GenTree* op1 = treeNode->gtGetOp1();
313313
GenTree* op2 = treeNode->gtGetOp2();
@@ -664,6 +664,9 @@ instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
664664
case GT_AND:
665665
ins = INS_AND;
666666
break;
667+
case GT_AND_NOT:
668+
ins = INS_bic;
669+
break;
667670
case GT_MUL:
668671
ins = INS_MUL;
669672
break;

src/coreclr/jit/codegenarm64.cpp

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,7 +1813,7 @@ void CodeGen::genCodeForMulHi(GenTreeOp* treeNode)
18131813
genProduceReg(treeNode);
18141814
}
18151815

1816-
// Generate code for ADD, SUB, MUL, DIV, UDIV, AND, OR and XOR
1816+
// Generate code for ADD, SUB, MUL, DIV, UDIV, AND, AND_NOT, OR and XOR
18171817
// This method is expected to have called genConsumeOperands() before calling it.
18181818
void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
18191819
{
@@ -1822,8 +1822,7 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
18221822
var_types targetType = treeNode->TypeGet();
18231823
emitter* emit = GetEmitter();
18241824

1825-
assert(oper == GT_ADD || oper == GT_SUB || oper == GT_MUL || oper == GT_DIV || oper == GT_UDIV || oper == GT_AND ||
1826-
oper == GT_OR || oper == GT_XOR);
1825+
assert(treeNode->OperIs(GT_ADD, GT_SUB, GT_MUL, GT_DIV, GT_UDIV, GT_AND, GT_AND_NOT, GT_OR, GT_XOR));
18271826

18281827
GenTree* op1 = treeNode->gtGetOp1();
18291828
GenTree* op2 = treeNode->gtGetOp2();
@@ -1842,6 +1841,9 @@ void CodeGen::genCodeForBinary(GenTreeOp* treeNode)
18421841
case GT_AND:
18431842
ins = INS_ands;
18441843
break;
1844+
case GT_AND_NOT:
1845+
ins = INS_bics;
1846+
break;
18451847
default:
18461848
noway_assert(!"Unexpected BinaryOp with GTF_SET_FLAGS set");
18471849
}
@@ -3115,6 +3117,9 @@ instruction CodeGen::genGetInsForOper(genTreeOps oper, var_types type)
31153117
case GT_AND:
31163118
ins = INS_and;
31173119
break;
3120+
case GT_AND_NOT:
3121+
ins = INS_bic;
3122+
break;
31183123
case GT_DIV:
31193124
ins = INS_sdiv;
31203125
break;

src/coreclr/jit/codegenarmarch.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,7 @@ void CodeGen::genCodeForTreeNode(GenTree* treeNode)
213213
case GT_OR:
214214
case GT_XOR:
215215
case GT_AND:
216+
case GT_AND_NOT:
216217
assert(varTypeIsIntegralOrI(treeNode));
217218

218219
FALLTHROUGH;

src/coreclr/jit/emitarm.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8095,7 +8095,7 @@ regNumber emitter::emitInsTernary(instruction ins, emitAttr attr, GenTree* dst,
80958095
if (dst->gtSetFlags())
80968096
{
80978097
assert((ins == INS_add) || (ins == INS_adc) || (ins == INS_sub) || (ins == INS_sbc) || (ins == INS_and) ||
8098-
(ins == INS_orr) || (ins == INS_eor) || (ins == INS_orn));
8098+
(ins == INS_orr) || (ins == INS_eor) || (ins == INS_orn) || (ins == INS_bic));
80998099
flags = INS_FLAGS_SET;
81008100
}
81018101

src/coreclr/jit/lower.cpp

Lines changed: 49 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,8 +139,7 @@ GenTree* Lowering::LowerNode(GenTree* node)
139139
case GT_AND:
140140
case GT_OR:
141141
case GT_XOR:
142-
ContainCheckBinary(node->AsOp());
143-
break;
142+
return LowerBinaryArithmeticCommon(node->AsOp());
144143

145144
case GT_MUL:
146145
case GT_MULHI:
@@ -5098,6 +5097,54 @@ GenTree* Lowering::LowerAdd(GenTreeOp* node)
50985097
return nullptr;
50995098
}
51005099

5100+
//------------------------------------------------------------------------
5101+
// LowerBinaryArithmeticCommon: lowers the given binary arithmetic node.
5102+
//
5103+
// Recognizes opportunities for using target-independent "combined" nodes
5104+
// (currently AND_NOT on ARMArch). Calls the target-specific "LowerBinaryArithmetic"
5105+
// method, which checks for more nodes and containment.
5106+
//
5107+
// Arguments:
5108+
// node - the arithmetic node to lower
5109+
//
5110+
// Returns:
5111+
// The next node to lower.
5112+
//
5113+
GenTree* Lowering::LowerBinaryArithmeticCommon(GenTreeOp* node)
5114+
{
5115+
// TODO-CQ-XArch: support BMI2 "andn" in codegen and condition
5116+
// this logic on the support for the instruction set on XArch.
5117+
CLANG_FORMAT_COMMENT_ANCHOR;
5118+
5119+
#ifdef TARGET_ARMARCH
5120+
if (comp->opts.OptimizationEnabled() && node->OperIs(GT_AND))
5121+
{
5122+
GenTree* opNode = nullptr;
5123+
GenTree* notNode = nullptr;
5124+
if (node->gtGetOp1()->OperIs(GT_NOT))
5125+
{
5126+
notNode = node->gtGetOp1();
5127+
opNode = node->gtGetOp2();
5128+
}
5129+
else if (node->gtGetOp2()->OperIs(GT_NOT))
5130+
{
5131+
notNode = node->gtGetOp2();
5132+
opNode = node->gtGetOp1();
5133+
}
5134+
5135+
if (notNode != nullptr)
5136+
{
5137+
node->gtOp1 = opNode;
5138+
node->gtOp2 = notNode->AsUnOp()->gtGetOp1();
5139+
node->ChangeOper(GT_AND_NOT);
5140+
BlockRange().Remove(notNode);
5141+
}
5142+
}
5143+
#endif // TARGET_ARMARCH
5144+
5145+
return LowerBinaryArithmetic(node);
5146+
}
5147+
51015148
//------------------------------------------------------------------------
51025149
// LowerUnsignedDivOrMod: Lowers a GT_UDIV/GT_UMOD node.
51035150
//

src/coreclr/jit/lower.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,8 @@ class Lowering final : public Phase
297297
void LowerStoreIndir(GenTreeStoreInd* node);
298298
GenTree* LowerAdd(GenTreeOp* node);
299299
GenTree* LowerMul(GenTreeOp* mul);
300+
GenTree* LowerBinaryArithmeticCommon(GenTreeOp* node);
301+
GenTree* LowerBinaryArithmetic(GenTreeOp* node);
300302
bool LowerUnsignedDivOrMod(GenTreeOp* divMod);
301303
GenTree* LowerConstIntDivOrMod(GenTree* node);
302304
GenTree* LowerSignedDivOrMod(GenTree* node);

src/coreclr/jit/lowerarmarch.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -277,6 +277,25 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul)
277277
return mul->gtNext;
278278
}
279279

280+
// LowerBinaryArithmetic: lowers the given binary arithmetic node.
281+
//
282+
// Currently only performs containment checks.
283+
//
284+
// TODO-CQ-ARMArch: take advantage of "madd" and "msub" here.
285+
//
286+
// Arguments:
287+
// node - the arithmetic node to lower
288+
//
289+
// Returns:
290+
// The next node to lower.
291+
//
292+
GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* node)
293+
{
294+
ContainCheckBinary(node);
295+
296+
return node->gtNext;
297+
}
298+
280299
//------------------------------------------------------------------------
281300
// LowerBlockStore: Lower a block store node
282301
//

src/coreclr/jit/lowerxarch.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,25 @@ GenTree* Lowering::LowerMul(GenTreeOp* mul)
190190
return mul->gtNext;
191191
}
192192

193+
// LowerBinaryArithmetic: lowers the given binary arithmetic node.
194+
//
195+
// Currently only performs containment checks.
196+
//
197+
// TODO-CQ-XArch: take advantage of the BMI instructions here.
198+
//
199+
// Arguments:
200+
// node - the arithmetic node to lower
201+
//
202+
// Returns:
203+
// The next node to lower.
204+
//
205+
GenTree* Lowering::LowerBinaryArithmetic(GenTreeOp* node)
206+
{
207+
ContainCheckBinary(node);
208+
209+
return node->gtNext;
210+
}
211+
193212
//------------------------------------------------------------------------
194213
// LowerBlockStore: Lower a block store node
195214
//

src/coreclr/jit/lsraarm.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -368,6 +368,7 @@ int LinearScan::BuildNode(GenTree* tree)
368368
FALLTHROUGH;
369369

370370
case GT_AND:
371+
case GT_AND_NOT:
371372
case GT_OR:
372373
case GT_XOR:
373374
case GT_LSH:

src/coreclr/jit/lsraarm64.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,7 @@ int LinearScan::BuildNode(GenTree* tree)
269269
FALLTHROUGH;
270270

271271
case GT_AND:
272+
case GT_AND_NOT:
272273
case GT_OR:
273274
case GT_XOR:
274275
case GT_LSH:

0 commit comments

Comments
 (0)