@@ -278,42 +278,38 @@ constantFoldBinaryWithOverflow(BuiltinInst *BI, BuiltinValueKind ID,
278
278
ResultsInError);
279
279
}
280
280
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 ();
284
293
285
294
// 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 ) {
288
297
return nullptr ;
289
298
}
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 ();
298
304
}
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 ();
311
307
}
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 );
317
313
}
318
314
319
315
static SILValue constantFoldIntrinsic (BuiltinInst *BI, llvm::Intrinsic::ID ID,
@@ -329,9 +325,13 @@ static SILValue constantFoldIntrinsic(BuiltinInst *BI, llvm::Intrinsic::ID ID,
329
325
return Op1;
330
326
}
331
327
332
- case llvm::Intrinsic::ctlz:
328
+ case llvm::Intrinsic::ctlz: {
329
+ return constantFoldCountLeadingOrTrialingZeroIntrinsic (
330
+ BI, true /* countLeadingZeros*/ );
331
+ }
333
332
case llvm::Intrinsic::cttz: {
334
- return countZeros (BI, ID);
333
+ return constantFoldCountLeadingOrTrialingZeroIntrinsic (
334
+ BI, false /* countLeadingZeros*/ );
335
335
}
336
336
337
337
case llvm::Intrinsic::sadd_with_overflow:
0 commit comments