@@ -2498,100 +2498,85 @@ bool VectorCombine::foldSelectShuffle(Instruction &I, bool FromReduction) {
2498
2498
// / instruction. Move ZExt if it is profitable
2499
2499
bool VectorCombine::shrinkType (llvm::Instruction &I) {
2500
2500
Value *ZExted, *OtherOperand;
2501
- if (match (&I, m_c_BinOp (m_ZExt (m_Value (ZExted)), m_Value (OtherOperand)))) {
2502
- if (I.getOpcode () != Instruction::And && I.getOpcode () != Instruction::Or &&
2503
- I.getOpcode () != Instruction::Xor && I.getOpcode () != Instruction::LShr)
2504
- return false ;
2501
+ if (!match (&I, m_c_BitwiseLogic (m_ZExt (m_Value (ZExted)),
2502
+ m_Value (OtherOperand))) &&
2503
+ !match (&I, m_LShr (m_ZExt (m_Value (ZExted)), m_Value (OtherOperand))))
2504
+ return false ;
2505
+
2506
+ Instruction *ZExtOperand =
2507
+ cast<Instruction>(I.getOperand (I.getOperand (0 ) == OtherOperand ? 1 : 0 ));
2508
+
2509
+ auto *BigTy = cast<FixedVectorType>(I.getType ());
2510
+ auto *SmallTy = cast<FixedVectorType>(ZExted->getType ());
2511
+ unsigned BW = SmallTy->getElementType ()->getPrimitiveSizeInBits ();
2512
+
2513
+ // Check that the expression overall uses at most the same number of bits as
2514
+ // ZExted
2515
+ KnownBits KB = computeKnownBits (&I, *DL);
2516
+ unsigned IBW = KB.getBitWidth () - KB.Zero .countLeadingOnes ();
2517
+ if (IBW > BW)
2518
+ return false ;
2519
+
2520
+ // Calculate costs of leaving current IR as it is and moving ZExt operation
2521
+ // later, along with adding truncates if needed
2522
+ InstructionCost ZExtCost = TTI.getCastInstrCost (
2523
+ Instruction::ZExt, BigTy, SmallTy,
2524
+ TargetTransformInfo::CastContextHint::None, TTI::TCK_RecipThroughput);
2525
+ InstructionCost CurrentCost = ZExtCost;
2526
+ InstructionCost ShrinkCost = 0 ;
2527
+
2528
+ // Calculate total cost and check that we can propagate through all ZExt users
2529
+ for (User *U : ZExtOperand->users ()) {
2530
+ auto *UI = cast<Instruction>(U);
2531
+ if (UI == &I) {
2532
+ CurrentCost += TTI.getArithmeticInstrCost (UI->getOpcode (), BigTy);
2533
+ ShrinkCost += TTI.getArithmeticInstrCost (UI->getOpcode (), SmallTy);
2534
+ ShrinkCost += ZExtCost;
2535
+ continue ;
2536
+ }
2505
2537
2506
- // In case of LShr extraction, ZExtOperand should be applied to the first
2507
- // operand
2508
- if (I.getOpcode () == Instruction::LShr && I.getOperand (1 ) != OtherOperand)
2538
+ if (!Instruction::isBinaryOp (UI->getOpcode ()))
2509
2539
return false ;
2510
2540
2511
- Instruction *ZExtOperand = cast<Instruction>(
2512
- I.getOperand (I.getOperand (0 ) == OtherOperand ? 1 : 0 ));
2513
-
2514
- auto *BigTy = cast<FixedVectorType>(I.getType ());
2515
- auto *SmallTy = cast<FixedVectorType>(ZExted->getType ());
2516
- auto BW = SmallTy->getElementType ()->getPrimitiveSizeInBits ();
2517
-
2518
- // Check that the expression overall uses at most the same number of bits as
2519
- // ZExted
2520
- auto KB = computeKnownBits (&I, *DL);
2521
- auto IBW = KB.getBitWidth () - KB.Zero .countLeadingOnes ();
2522
- if (IBW > BW)
2541
+ // Check if we can propagate ZExt through its other users
2542
+ KB = computeKnownBits (UI, *DL);
2543
+ unsigned UBW = KB.getBitWidth () - KB.Zero .countLeadingOnes ();
2544
+ if (UBW > BW)
2523
2545
return false ;
2524
2546
2525
- bool HasUNZExtableUser = false ;
2547
+ CurrentCost += TTI.getArithmeticInstrCost (UI->getOpcode (), BigTy);
2548
+ ShrinkCost += TTI.getArithmeticInstrCost (UI->getOpcode (), SmallTy);
2549
+ ShrinkCost += ZExtCost;
2550
+ }
2526
2551
2527
- // Calculate costs of leaving current IR as it is and moving ZExt operation
2528
- // later, along with adding truncates if needed
2529
- InstructionCost ZExtCost = TTI.getCastInstrCost (
2530
- Instruction::ZExt, BigTy, SmallTy,
2552
+ // If the other instruction operand is not a constant, we'll need to
2553
+ // generate a truncate instruction. So we have to adjust cost
2554
+ if (!isa<Constant>(OtherOperand))
2555
+ ShrinkCost += TTI.getCastInstrCost (
2556
+ Instruction::Trunc, SmallTy, BigTy,
2531
2557
TargetTransformInfo::CastContextHint::None, TTI::TCK_RecipThroughput);
2532
- InstructionCost CurrentCost = ZExtCost;
2533
- InstructionCost ShrinkCost = 0 ;
2534
-
2535
- for (User *U : ZExtOperand->users ()) {
2536
- auto *UI = cast<Instruction>(U);
2537
- if (UI == &I) {
2538
- CurrentCost += TTI.getArithmeticInstrCost (UI->getOpcode (), BigTy);
2539
- ShrinkCost += TTI.getArithmeticInstrCost (UI->getOpcode (), SmallTy);
2540
- ShrinkCost += ZExtCost;
2541
- continue ;
2542
- }
2543
-
2544
- if (!Instruction::isBinaryOp (UI->getOpcode ())) {
2545
- HasUNZExtableUser = true ;
2546
- continue ;
2547
- }
2548
-
2549
- // Check if we can propagate ZExt through its other users
2550
- auto KB = computeKnownBits (UI, *DL);
2551
- auto UBW = KB.getBitWidth () - KB.Zero .countLeadingOnes ();
2552
- if (UBW <= BW) {
2553
- CurrentCost += TTI.getArithmeticInstrCost (UI->getOpcode (), BigTy);
2554
- ShrinkCost += TTI.getArithmeticInstrCost (UI->getOpcode (), SmallTy);
2555
- ShrinkCost += ZExtCost;
2556
- } else {
2557
- HasUNZExtableUser = true ;
2558
- }
2559
- }
2560
2558
2561
- // ZExt can't remove, add extra cost
2562
- if (HasUNZExtableUser)
2563
- ShrinkCost += ZExtCost;
2564
-
2565
- // If the other instruction operand is not a constant, we'll need to
2566
- // generate a truncate instruction. So we have to adjust cost
2567
- if (!isa<Constant>(OtherOperand))
2568
- ShrinkCost += TTI.getCastInstrCost (
2569
- Instruction::Trunc, SmallTy, BigTy,
2570
- TargetTransformInfo::CastContextHint::None, TTI::TCK_RecipThroughput);
2571
-
2572
- // If the cost of shrinking types and leaving the IR is the same, we'll lean
2573
- // towards modifying the IR because shrinking opens opportunities for other
2574
- // shrinking optimisations.
2575
- if (ShrinkCost > CurrentCost)
2576
- return false ;
2559
+ // If the cost of shrinking types and leaving the IR is the same, we'll lean
2560
+ // towards modifying the IR because shrinking opens opportunities for other
2561
+ // shrinking optimisations.
2562
+ if (ShrinkCost > CurrentCost)
2563
+ return false ;
2577
2564
2578
- auto *Op0 = ZExted;
2579
- if (auto *OI = dyn_cast<Instruction>(OtherOperand))
2580
- Builder.SetInsertPoint (OI->getNextNode ());
2581
- auto *Op1 = Builder.CreateTrunc (OtherOperand, SmallTy);
2582
- Builder.SetInsertPoint (&I);
2583
- // Keep the order of operands the same
2584
- if (I.getOperand (0 ) == OtherOperand)
2585
- std::swap (Op0, Op1);
2586
- auto *NewBinOp =
2587
- Builder.CreateBinOp ((Instruction::BinaryOps)I.getOpcode (), Op0, Op1);
2588
- cast<Instruction>(NewBinOp)->copyIRFlags (&I);
2589
- cast<Instruction>(NewBinOp)->copyMetadata (I);
2590
- auto *NewZExtr = Builder.CreateZExt (NewBinOp, BigTy);
2591
- replaceValue (I, *NewZExtr);
2592
- return true ;
2593
- }
2594
- return false ;
2565
+ Value *Op0 = ZExted;
2566
+ if (auto *OI = dyn_cast<Instruction>(OtherOperand))
2567
+ Builder.SetInsertPoint (OI->getNextNode ());
2568
+ Value *Op1 = Builder.CreateTrunc (OtherOperand, SmallTy);
2569
+ Builder.SetInsertPoint (&I);
2570
+ // Keep the order of operands the same
2571
+ if (I.getOperand (0 ) == OtherOperand)
2572
+ std::swap (Op0, Op1);
2573
+ Value *NewBinOp =
2574
+ Builder.CreateBinOp ((Instruction::BinaryOps)I.getOpcode (), Op0, Op1);
2575
+ cast<Instruction>(NewBinOp)->copyIRFlags (&I);
2576
+ cast<Instruction>(NewBinOp)->copyMetadata (I);
2577
+ Value *NewZExtr = Builder.CreateZExt (NewBinOp, BigTy);
2578
+ replaceValue (I, *NewZExtr);
2579
+ return true ;
2595
2580
}
2596
2581
2597
2582
// / This is the entry point for all transforms. Pass manager differences are
0 commit comments