@@ -661,14 +661,13 @@ static bool canShiftBinOpWithConstantRHS(BinaryOperator &Shift,
661
661
662
662
Instruction *InstCombinerImpl::FoldShiftByConstant (Value *Op0, Constant *Op1,
663
663
BinaryOperator &I) {
664
- bool IsLeftShift = I.getOpcode () == Instruction::Shl;
665
-
666
664
const APInt *Op1C;
667
665
if (!match (Op1, m_APInt (Op1C)))
668
666
return nullptr ;
669
667
670
668
// See if we can propagate this shift into the input, this covers the trivial
671
669
// cast of lshr(shl(x,c1),c2) as well as other more complex cases.
670
+ bool IsLeftShift = I.getOpcode () == Instruction::Shl;
672
671
if (I.getOpcode () != Instruction::AShr &&
673
672
canEvaluateShifted (Op0, Op1C->getZExtValue (), IsLeftShift, *this , &I)) {
674
673
LLVM_DEBUG (
@@ -693,118 +692,7 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
693
692
if (!Op0->hasOneUse ())
694
693
return nullptr ;
695
694
696
- // Fold shift2(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
697
- // If 'shift2' is an ashr, we would have to get the sign bit into a funny
698
- // place. Don't try to do this transformation in this case. Also, we
699
- // require that the input operand is a non-poison shift-by-constant so that we
700
- // have confidence that the shifts will get folded together. We could do this
701
- // xform in more cases, but it is unlikely to be profitable.
702
- Instruction *TrOp;
703
- const APInt *TrShiftAmt;
704
- if (IsLeftShift && match (Op0, m_Trunc (m_Instruction (TrOp))) &&
705
- match (TrOp, m_OneUse (m_Shift (m_Value (), m_APInt (TrShiftAmt)))) &&
706
- TrShiftAmt->ult (TrOp->getType ()->getScalarSizeInBits ())) {
707
- Type *SrcTy = TrOp->getType ();
708
-
709
- // Okay, we'll do this xform. Make the shift of shift.
710
- Constant *ShAmt = ConstantExpr::getZExt (Op1, SrcTy);
711
- // (shift2 (shift1 & 0x00FF), c2)
712
- Value *NSh = Builder.CreateBinOp (I.getOpcode (), TrOp, ShAmt, I.getName ());
713
-
714
- // For logical shifts, the truncation has the effect of making the high
715
- // part of the register be zeros. Emulate this by inserting an AND to
716
- // clear the top bits as needed. This 'and' will usually be zapped by
717
- // other xforms later if dead.
718
- unsigned SrcSize = SrcTy->getScalarSizeInBits ();
719
- Constant *MaskV =
720
- ConstantInt::get (SrcTy, APInt::getLowBitsSet (SrcSize, TypeBits));
721
-
722
- // The mask we constructed says what the trunc would do if occurring
723
- // between the shifts. We want to know the effect *after* the second
724
- // shift. We know that it is a logical shift by a constant, so adjust the
725
- // mask as appropriate.
726
- MaskV = ConstantExpr::get (I.getOpcode (), MaskV, ShAmt);
727
- // shift1 & 0x00FF
728
- Value *And = Builder.CreateAnd (NSh, MaskV, Op0->getName ());
729
- // Return the value truncated to the interesting size.
730
- return new TruncInst (And, Ty);
731
- }
732
-
733
695
if (auto *Op0BO = dyn_cast<BinaryOperator>(Op0)) {
734
- // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
735
- Value *V1;
736
- const APInt *CC;
737
- switch (Op0BO->getOpcode ()) {
738
- default :
739
- break ;
740
- case Instruction::Add:
741
- case Instruction::And:
742
- case Instruction::Or:
743
- case Instruction::Xor: {
744
- // These operators commute.
745
- // Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C)
746
- if (IsLeftShift && Op0BO->getOperand (1 )->hasOneUse () &&
747
- match (Op0BO->getOperand (1 ), m_Shr (m_Value (V1), m_Specific (Op1)))) {
748
- Value *YS = // (Y << C)
749
- Builder.CreateShl (Op0BO->getOperand (0 ), Op1, Op0BO->getName ());
750
- // (X + (Y << C))
751
- Value *X = Builder.CreateBinOp (Op0BO->getOpcode (), YS, V1,
752
- Op0BO->getOperand (1 )->getName ());
753
- unsigned Op1Val = Op1C->getLimitedValue (TypeBits);
754
- APInt Bits = APInt::getHighBitsSet (TypeBits, TypeBits - Op1Val);
755
- Constant *Mask = ConstantInt::get (Ty, Bits);
756
- return BinaryOperator::CreateAnd (X, Mask);
757
- }
758
-
759
- // Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C))
760
- Value *Op0BOOp1 = Op0BO->getOperand (1 );
761
- if (IsLeftShift && Op0BOOp1->hasOneUse () &&
762
- match (Op0BOOp1, m_And (m_OneUse (m_Shr (m_Value (V1), m_Specific (Op1))),
763
- m_APInt (CC)))) {
764
- Value *YS = // (Y << C)
765
- Builder.CreateShl (Op0BO->getOperand (0 ), Op1, Op0BO->getName ());
766
- // X & (CC << C)
767
- Value *XM = Builder.CreateAnd (
768
- V1, ConstantExpr::getShl (ConstantInt::get (Ty, *CC), Op1),
769
- V1->getName () + " .mask" );
770
- return BinaryOperator::Create (Op0BO->getOpcode (), YS, XM);
771
- }
772
- LLVM_FALLTHROUGH;
773
- }
774
-
775
- case Instruction::Sub: {
776
- // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
777
- if (IsLeftShift && Op0BO->getOperand (0 )->hasOneUse () &&
778
- match (Op0BO->getOperand (0 ), m_Shr (m_Value (V1), m_Specific (Op1)))) {
779
- Value *YS = // (Y << C)
780
- Builder.CreateShl (Op0BO->getOperand (1 ), Op1, Op0BO->getName ());
781
- // (X + (Y << C))
782
- Value *X = Builder.CreateBinOp (Op0BO->getOpcode (), V1, YS,
783
- Op0BO->getOperand (0 )->getName ());
784
- unsigned Op1Val = Op1C->getLimitedValue (TypeBits);
785
- APInt Bits = APInt::getHighBitsSet (TypeBits, TypeBits - Op1Val);
786
- Constant *Mask = ConstantInt::get (Ty, Bits);
787
- return BinaryOperator::CreateAnd (X, Mask);
788
- }
789
-
790
- // Turn (((X >> C)&CC) + Y) << C -> (X + (Y << C)) & (CC << C)
791
- if (IsLeftShift && Op0BO->getOperand (0 )->hasOneUse () &&
792
- match (Op0BO->getOperand (0 ),
793
- m_And (m_OneUse (m_Shr (m_Value (V1), m_Specific (Op1))),
794
- m_APInt (CC)))) {
795
- Value *YS = // (Y << C)
796
- Builder.CreateShl (Op0BO->getOperand (1 ), Op1, Op0BO->getName ());
797
- // X & (CC << C)
798
- Value *XM = Builder.CreateAnd (
799
- V1, ConstantExpr::getShl (ConstantInt::get (Ty, *CC), Op1),
800
- V1->getName () + " .mask" );
801
- return BinaryOperator::Create (Op0BO->getOpcode (), XM, YS);
802
- }
803
-
804
- break ;
805
- }
806
- }
807
-
808
696
// If the operand is a bitwise operator with a constant RHS, and the
809
697
// shift is the only use, we can pull it out of the shift.
810
698
const APInt *Op0C;
@@ -820,20 +708,6 @@ Instruction *InstCombinerImpl::FoldShiftByConstant(Value *Op0, Constant *Op1,
820
708
return BinaryOperator::Create (Op0BO->getOpcode (), NewShift, NewRHS);
821
709
}
822
710
}
823
-
824
- // If the operand is a subtract with a constant LHS, and the shift
825
- // is the only use, we can pull it out of the shift.
826
- // This folds (shl (sub C1, X), C2) -> (sub (C1 << C2), (shl X, C2))
827
- if (IsLeftShift && Op0BO->getOpcode () == Instruction::Sub &&
828
- match (Op0BO->getOperand (0 ), m_APInt (Op0C))) {
829
- Constant *NewRHS = ConstantExpr::get (
830
- I.getOpcode (), cast<Constant>(Op0BO->getOperand (0 )), Op1);
831
-
832
- Value *NewShift = Builder.CreateShl (Op0BO->getOperand (1 ), Op1);
833
- NewShift->takeName (Op0BO);
834
-
835
- return BinaryOperator::CreateSub (NewRHS, NewShift);
836
- }
837
711
}
838
712
839
713
// If we have a select that conditionally executes some binary operator,
@@ -978,6 +852,129 @@ Instruction *InstCombinerImpl::visitShl(BinaryOperator &I) {
978
852
return BinaryOperator::CreateShl (X, ConstantInt::get (Ty, AmtSum));
979
853
}
980
854
855
+ // Fold shl(trunc(shift1(x,c1)), c2) -> trunc(shift2(shift1(x,c1),c2))
856
+ // If 'shift2' is an ashr, we would have to get the sign bit into a funny
857
+ // place. Don't try to do this transformation in this case. Also, we
858
+ // require that the input operand is a non-poison shift-by-constant so that
859
+ // we have confidence that the shifts will get folded together.
860
+ Instruction *TrOp;
861
+ const APInt *TrShiftAmt;
862
+ if (match (Op0, m_Trunc (m_Instruction (TrOp))) &&
863
+ match (TrOp, m_OneUse (m_Shift (m_Value (), m_APInt (TrShiftAmt)))) &&
864
+ TrShiftAmt->ult (TrOp->getType ()->getScalarSizeInBits ())) {
865
+ Type *SrcTy = TrOp->getType ();
866
+
867
+ // Okay, we'll do this xform. Make the shift of shift.
868
+ unsigned SrcSize = SrcTy->getScalarSizeInBits ();
869
+ Constant *ShAmt = ConstantInt::get (SrcTy, C->zext (SrcSize));
870
+
871
+ // (shift2 (shift1 & 0x00FF), c2)
872
+ Value *NSh = Builder.CreateBinOp (I.getOpcode (), TrOp, ShAmt, I.getName ());
873
+
874
+ // For logical shifts, the truncation has the effect of making the high
875
+ // part of the register be zeros. Emulate this by inserting an AND to
876
+ // clear the top bits as needed. This 'and' will usually be zapped by
877
+ // other xforms later if dead.
878
+ Constant *MaskV =
879
+ ConstantInt::get (SrcTy, APInt::getLowBitsSet (SrcSize, BitWidth));
880
+
881
+ // The mask we constructed says what the trunc would do if occurring
882
+ // between the shifts. We want to know the effect *after* the second
883
+ // shift. We know that it is a logical shift by a constant, so adjust the
884
+ // mask as appropriate.
885
+ MaskV = ConstantExpr::get (I.getOpcode (), MaskV, ShAmt);
886
+ // shift1 & 0x00FF
887
+ Value *And = Builder.CreateAnd (NSh, MaskV, Op0->getName ());
888
+ // Return the value truncated to the interesting size.
889
+ return new TruncInst (And, Ty);
890
+ }
891
+
892
+ BinaryOperator *Op0BO;
893
+ if (match (Op0, m_OneUse (m_BinOp (Op0BO)))) {
894
+ // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
895
+ Value *V1;
896
+ const APInt *CC;
897
+ switch (Op0BO->getOpcode ()) {
898
+ default :
899
+ break ;
900
+ case Instruction::Add:
901
+ case Instruction::And:
902
+ case Instruction::Or:
903
+ case Instruction::Xor: {
904
+ // These operators commute.
905
+ // Turn (Y + (X >> C)) << C -> (X + (Y << C)) & (~0 << C)
906
+ if (Op0BO->getOperand (1 )->hasOneUse () &&
907
+ match (Op0BO->getOperand (1 ), m_Shr (m_Value (V1), m_Specific (Op1)))) {
908
+ Value *YS = // (Y << C)
909
+ Builder.CreateShl (Op0BO->getOperand (0 ), Op1, Op0BO->getName ());
910
+ // (X + (Y << C))
911
+ Value *X = Builder.CreateBinOp (Op0BO->getOpcode (), YS, V1,
912
+ Op0BO->getOperand (1 )->getName ());
913
+ unsigned Op1Val = C->getLimitedValue (BitWidth);
914
+ APInt Bits = APInt::getHighBitsSet (BitWidth, BitWidth - Op1Val);
915
+ Constant *Mask = ConstantInt::get (Ty, Bits);
916
+ return BinaryOperator::CreateAnd (X, Mask);
917
+ }
918
+
919
+ // Turn (Y + ((X >> C) & CC)) << C -> ((X & (CC << C)) + (Y << C))
920
+ Value *Op0BOOp1 = Op0BO->getOperand (1 );
921
+ if (Op0BOOp1->hasOneUse () &&
922
+ match (Op0BOOp1, m_And (m_OneUse (m_Shr (m_Value (V1), m_Specific (Op1))),
923
+ m_APInt (CC)))) {
924
+ Value *YS = // (Y << C)
925
+ Builder.CreateShl (Op0BO->getOperand (0 ), Op1, Op0BO->getName ());
926
+ // X & (CC << C)
927
+ Value *XM = Builder.CreateAnd (V1, ConstantInt::get (Ty, CC->shl (*C)),
928
+ V1->getName () + " .mask" );
929
+ return BinaryOperator::Create (Op0BO->getOpcode (), YS, XM);
930
+ }
931
+ LLVM_FALLTHROUGH;
932
+ }
933
+
934
+ case Instruction::Sub: {
935
+ // Turn ((X >> C) + Y) << C -> (X + (Y << C)) & (~0 << C)
936
+ if (Op0BO->getOperand (0 )->hasOneUse () &&
937
+ match (Op0BO->getOperand (0 ), m_Shr (m_Value (V1), m_Specific (Op1)))) {
938
+ Value *YS = // (Y << C)
939
+ Builder.CreateShl (Op0BO->getOperand (1 ), Op1, Op0BO->getName ());
940
+ // (X + (Y << C))
941
+ Value *X = Builder.CreateBinOp (Op0BO->getOpcode (), V1, YS,
942
+ Op0BO->getOperand (0 )->getName ());
943
+ unsigned Op1Val = C->getLimitedValue (BitWidth);
944
+ APInt Bits = APInt::getHighBitsSet (BitWidth, BitWidth - Op1Val);
945
+ Constant *Mask = ConstantInt::get (Ty, Bits);
946
+ return BinaryOperator::CreateAnd (X, Mask);
947
+ }
948
+
949
+ // Turn (((X >> C)&CC) + Y) << C -> (X + (Y << C)) & (CC << C)
950
+ if (Op0BO->getOperand (0 )->hasOneUse () &&
951
+ match (Op0BO->getOperand (0 ),
952
+ m_And (m_OneUse (m_Shr (m_Value (V1), m_Specific (Op1))),
953
+ m_APInt (CC)))) {
954
+ Value *YS = // (Y << C)
955
+ Builder.CreateShl (Op0BO->getOperand (1 ), Op1, Op0BO->getName ());
956
+ // X & (CC << C)
957
+ Value *XM = Builder.CreateAnd (V1, ConstantInt::get (Ty, CC->shl (*C)),
958
+ V1->getName () + " .mask" );
959
+ return BinaryOperator::Create (Op0BO->getOpcode (), XM, YS);
960
+ }
961
+
962
+ break ;
963
+ }
964
+ }
965
+
966
+ // If the operand is a subtract with a constant LHS, and the shift
967
+ // is the only use, we can pull it out of the shift.
968
+ // This folds (shl (sub C1, X), C) -> (sub (C1 << C), (shl X, C))
969
+ if (Op0BO->getOpcode () == Instruction::Sub &&
970
+ match (Op0BO->getOperand (0 ), m_APInt (C1))) {
971
+ Constant *NewLHS = ConstantInt::get (Ty, C1->shl (*C));
972
+ Value *NewShift = Builder.CreateShl (Op0BO->getOperand (1 ), Op1);
973
+ NewShift->takeName (Op0BO);
974
+ return BinaryOperator::CreateSub (NewLHS, NewShift);
975
+ }
976
+ }
977
+
981
978
// If the shifted-out value is known-zero, then this is a NUW shift.
982
979
if (!I.hasNoUnsignedWrap () &&
983
980
MaskedValueIsZero (Op0, APInt::getHighBitsSet (BitWidth, ShAmtC), 0 ,
0 commit comments