@@ -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
319315static 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