Skip to content

Commit 52e8340

Browse files
authored
Merge pull request #23739 from shajrawi/cttz2
2 parents f0b7f96 + de0287d commit 52e8340

File tree

1 file changed

+32
-32
lines changed

1 file changed

+32
-32
lines changed

lib/SILOptimizer/Utils/ConstantFolding.cpp

Lines changed: 32 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -278,42 +278,38 @@ constantFoldBinaryWithOverflow(BuiltinInst *BI, BuiltinValueKind ID,
278278
ResultsInError);
279279
}
280280

281-
static SILValue countZeros(BuiltinInst *BI, llvm::Intrinsic::ID ID) {
282-
assert(BI->getArguments().size() == 2 && "Ctlz should have 2 args.");
283-
OperandValueArrayRef Args = BI->getArguments();
281+
/// Constant fold a cttz or ctlz builtin inst of an integer literal.
282+
/// If \p countLeadingZeros is set to true, then we assume \p bi must be ctlz.
283+
/// If false, \p bi must be cttz.
284+
///
285+
/// NOTE: We assert that \p bi is either cttz or ctlz.
286+
static SILValue
287+
constantFoldCountLeadingOrTrialingZeroIntrinsic(BuiltinInst *bi,
288+
bool countLeadingZeros) {
289+
assert(bi->getIntrinsicID() == llvm::Intrinsic::ctlz ||
290+
bi->getIntrinsicID() == llvm::Intrinsic::cttz &&
291+
"Invalid Intrinsic - expected Ctlz/Cllz");
292+
OperandValueArrayRef args = bi->getArguments();
284293

285294
// Fold for integer constant arguments.
286-
auto *LHS = dyn_cast<IntegerLiteralInst>(Args[0]);
287-
if (!LHS) {
295+
auto *lhs = dyn_cast<IntegerLiteralInst>(args[0]);
296+
if (!lhs) {
288297
return nullptr;
289298
}
290-
APInt LHSI = LHS->getValue();
291-
unsigned LZ = 0;
292-
// Check corner-case of source == zero
293-
if (LHSI == 0) {
294-
auto *RHS = dyn_cast<IntegerLiteralInst>(Args[1]);
295-
if (!RHS || RHS->getValue() != 0) {
296-
// Undefined
297-
return nullptr;
299+
APInt lhsi = lhs->getValue();
300+
unsigned lz = [&] {
301+
if (lhsi == 0) {
302+
// Check corner-case of source == zero
303+
return lhsi.getBitWidth();
298304
}
299-
LZ = LHSI.getBitWidth();
300-
} else {
301-
switch (ID) {
302-
default:
303-
return nullptr;
304-
case llvm::Intrinsic::ctlz: {
305-
LZ = LHSI.countLeadingZeros();
306-
break;
307-
}
308-
case llvm::Intrinsic::cttz: {
309-
LZ = LHSI.countTrailingZeros();
310-
break;
305+
if (countLeadingZeros) {
306+
return lhsi.countLeadingZeros();
311307
}
312-
}
313-
}
314-
APInt LZAsAPInt = APInt(LHSI.getBitWidth(), LZ);
315-
SILBuilderWithScope B(BI);
316-
return B.createIntegerLiteral(BI->getLoc(), LHS->getType(), LZAsAPInt);
308+
return lhsi.countTrailingZeros();
309+
}();
310+
APInt lzAsAPInt = APInt(lhsi.getBitWidth(), lz);
311+
SILBuilderWithScope builder(bi);
312+
return builder.createIntegerLiteral(bi->getLoc(), lhs->getType(), lzAsAPInt);
317313
}
318314

319315
static SILValue constantFoldIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID,
@@ -329,9 +325,13 @@ static SILValue constantFoldIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID,
329325
return Op1;
330326
}
331327

332-
case llvm::Intrinsic::ctlz:
328+
case llvm::Intrinsic::ctlz: {
329+
return constantFoldCountLeadingOrTrialingZeroIntrinsic(
330+
BI, true /*countLeadingZeros*/);
331+
}
333332
case llvm::Intrinsic::cttz: {
334-
return countZeros(BI, ID);
333+
return constantFoldCountLeadingOrTrialingZeroIntrinsic(
334+
BI, false /*countLeadingZeros*/);
335335
}
336336

337337
case llvm::Intrinsic::sadd_with_overflow:

0 commit comments

Comments
 (0)