@@ -759,35 +759,42 @@ Value *InstCombiner::SimplifyUsingDistributiveLaws(BinaryOperator &I) {
759
759
760
760
Value *InstCombiner::SimplifySelectsFeedingBinaryOp (BinaryOperator &I,
761
761
Value *LHS, Value *RHS) {
762
- Instruction::BinaryOps Opcode = I.getOpcode ();
763
- // (op (select (a, b, c)), (select (a, d, e))) -> (select (a, (op b, d), (op
764
- // c, e)))
765
- Value *A, *B, *C, *D, *E;
766
- Value *SI = nullptr ;
767
- if (match (LHS, m_Select (m_Value (A), m_Value (B), m_Value (C))) &&
768
- match (RHS, m_Select (m_Specific (A), m_Value (D), m_Value (E)))) {
769
- bool SelectsHaveOneUse = LHS->hasOneUse () && RHS->hasOneUse ();
770
-
771
- FastMathFlags FMF;
772
- BuilderTy::FastMathFlagGuard Guard (Builder);
773
- if (isa<FPMathOperator>(&I)) {
774
- FMF = I.getFastMathFlags ();
775
- Builder.setFastMathFlags (FMF);
776
- }
762
+ Value *A, *B, *C, *D, *E, *F;
763
+ bool LHSIsSelect = match (LHS, m_Select (m_Value (A), m_Value (B), m_Value (C)));
764
+ bool RHSIsSelect = match (RHS, m_Select (m_Value (D), m_Value (E), m_Value (F)));
765
+ if (!LHSIsSelect && !RHSIsSelect)
766
+ return nullptr ;
777
767
778
- Value *V1 = SimplifyBinOp (Opcode, C, E, FMF, SQ.getWithInstruction (&I));
779
- Value *V2 = SimplifyBinOp (Opcode, B, D, FMF, SQ.getWithInstruction (&I));
780
- if (V1 && V2)
781
- SI = Builder.CreateSelect (A, V2, V1);
782
- else if (V2 && SelectsHaveOneUse)
783
- SI = Builder.CreateSelect (A, V2, Builder.CreateBinOp (Opcode, C, E));
784
- else if (V1 && SelectsHaveOneUse)
785
- SI = Builder.CreateSelect (A, Builder.CreateBinOp (Opcode, B, D), V1);
768
+ FastMathFlags FMF;
769
+ BuilderTy::FastMathFlagGuard Guard (Builder);
770
+ if (isa<FPMathOperator>(&I)) {
771
+ FMF = I.getFastMathFlags ();
772
+ Builder.setFastMathFlags (FMF);
773
+ }
786
774
787
- if (SI)
788
- SI->takeName (&I);
775
+ Instruction::BinaryOps Opcode = I.getOpcode ();
776
+ SimplifyQuery Q = SQ.getWithInstruction (&I);
777
+
778
+ Value *Cond, *True = nullptr , *False = nullptr ;
779
+ if (LHSIsSelect && RHSIsSelect && A == D) {
780
+ // (A ? B : C) op (A ? E : F) -> A ? (B op E) : (C op F)
781
+ Cond = A;
782
+ True = SimplifyBinOp (Opcode, B, E, FMF, Q);
783
+ False = SimplifyBinOp (Opcode, C, F, FMF, Q);
784
+
785
+ if (LHS->hasOneUse () && RHS->hasOneUse ()) {
786
+ if (False && !True)
787
+ True = Builder.CreateBinOp (Opcode, B, E);
788
+ else if (True && !False)
789
+ False = Builder.CreateBinOp (Opcode, C, F);
790
+ }
789
791
}
790
792
793
+ if (!True || !False)
794
+ return nullptr ;
795
+
796
+ Value *SI = Builder.CreateSelect (Cond, True, False);
797
+ SI->takeName (&I);
791
798
return SI;
792
799
}
793
800
0 commit comments