1*9880d681SAndroid Build Coastguard Worker //===- InstCombineSelect.cpp ----------------------------------------------===//
2*9880d681SAndroid Build Coastguard Worker //
3*9880d681SAndroid Build Coastguard Worker // The LLVM Compiler Infrastructure
4*9880d681SAndroid Build Coastguard Worker //
5*9880d681SAndroid Build Coastguard Worker // This file is distributed under the University of Illinois Open Source
6*9880d681SAndroid Build Coastguard Worker // License. See LICENSE.TXT for details.
7*9880d681SAndroid Build Coastguard Worker //
8*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
9*9880d681SAndroid Build Coastguard Worker //
10*9880d681SAndroid Build Coastguard Worker // This file implements the visitSelect function.
11*9880d681SAndroid Build Coastguard Worker //
12*9880d681SAndroid Build Coastguard Worker //===----------------------------------------------------------------------===//
13*9880d681SAndroid Build Coastguard Worker
14*9880d681SAndroid Build Coastguard Worker #include "InstCombineInternal.h"
15*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ConstantFolding.h"
16*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/InstructionSimplify.h"
17*9880d681SAndroid Build Coastguard Worker #include "llvm/Analysis/ValueTracking.h"
18*9880d681SAndroid Build Coastguard Worker #include "llvm/IR/PatternMatch.h"
19*9880d681SAndroid Build Coastguard Worker using namespace llvm;
20*9880d681SAndroid Build Coastguard Worker using namespace PatternMatch;
21*9880d681SAndroid Build Coastguard Worker
22*9880d681SAndroid Build Coastguard Worker #define DEBUG_TYPE "instcombine"
23*9880d681SAndroid Build Coastguard Worker
24*9880d681SAndroid Build Coastguard Worker static SelectPatternFlavor
getInverseMinMaxSelectPattern(SelectPatternFlavor SPF)25*9880d681SAndroid Build Coastguard Worker getInverseMinMaxSelectPattern(SelectPatternFlavor SPF) {
26*9880d681SAndroid Build Coastguard Worker switch (SPF) {
27*9880d681SAndroid Build Coastguard Worker default:
28*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unhandled!");
29*9880d681SAndroid Build Coastguard Worker
30*9880d681SAndroid Build Coastguard Worker case SPF_SMIN:
31*9880d681SAndroid Build Coastguard Worker return SPF_SMAX;
32*9880d681SAndroid Build Coastguard Worker case SPF_UMIN:
33*9880d681SAndroid Build Coastguard Worker return SPF_UMAX;
34*9880d681SAndroid Build Coastguard Worker case SPF_SMAX:
35*9880d681SAndroid Build Coastguard Worker return SPF_SMIN;
36*9880d681SAndroid Build Coastguard Worker case SPF_UMAX:
37*9880d681SAndroid Build Coastguard Worker return SPF_UMIN;
38*9880d681SAndroid Build Coastguard Worker }
39*9880d681SAndroid Build Coastguard Worker }
40*9880d681SAndroid Build Coastguard Worker
getCmpPredicateForMinMax(SelectPatternFlavor SPF,bool Ordered=false)41*9880d681SAndroid Build Coastguard Worker static CmpInst::Predicate getCmpPredicateForMinMax(SelectPatternFlavor SPF,
42*9880d681SAndroid Build Coastguard Worker bool Ordered=false) {
43*9880d681SAndroid Build Coastguard Worker switch (SPF) {
44*9880d681SAndroid Build Coastguard Worker default:
45*9880d681SAndroid Build Coastguard Worker llvm_unreachable("unhandled!");
46*9880d681SAndroid Build Coastguard Worker
47*9880d681SAndroid Build Coastguard Worker case SPF_SMIN:
48*9880d681SAndroid Build Coastguard Worker return ICmpInst::ICMP_SLT;
49*9880d681SAndroid Build Coastguard Worker case SPF_UMIN:
50*9880d681SAndroid Build Coastguard Worker return ICmpInst::ICMP_ULT;
51*9880d681SAndroid Build Coastguard Worker case SPF_SMAX:
52*9880d681SAndroid Build Coastguard Worker return ICmpInst::ICMP_SGT;
53*9880d681SAndroid Build Coastguard Worker case SPF_UMAX:
54*9880d681SAndroid Build Coastguard Worker return ICmpInst::ICMP_UGT;
55*9880d681SAndroid Build Coastguard Worker case SPF_FMINNUM:
56*9880d681SAndroid Build Coastguard Worker return Ordered ? FCmpInst::FCMP_OLT : FCmpInst::FCMP_ULT;
57*9880d681SAndroid Build Coastguard Worker case SPF_FMAXNUM:
58*9880d681SAndroid Build Coastguard Worker return Ordered ? FCmpInst::FCMP_OGT : FCmpInst::FCMP_UGT;
59*9880d681SAndroid Build Coastguard Worker }
60*9880d681SAndroid Build Coastguard Worker }
61*9880d681SAndroid Build Coastguard Worker
generateMinMaxSelectPattern(InstCombiner::BuilderTy * Builder,SelectPatternFlavor SPF,Value * A,Value * B)62*9880d681SAndroid Build Coastguard Worker static Value *generateMinMaxSelectPattern(InstCombiner::BuilderTy *Builder,
63*9880d681SAndroid Build Coastguard Worker SelectPatternFlavor SPF, Value *A,
64*9880d681SAndroid Build Coastguard Worker Value *B) {
65*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Pred = getCmpPredicateForMinMax(SPF);
66*9880d681SAndroid Build Coastguard Worker assert(CmpInst::isIntPredicate(Pred));
67*9880d681SAndroid Build Coastguard Worker return Builder->CreateSelect(Builder->CreateICmp(Pred, A, B), A, B);
68*9880d681SAndroid Build Coastguard Worker }
69*9880d681SAndroid Build Coastguard Worker
70*9880d681SAndroid Build Coastguard Worker /// We want to turn code that looks like this:
71*9880d681SAndroid Build Coastguard Worker /// %C = or %A, %B
72*9880d681SAndroid Build Coastguard Worker /// %D = select %cond, %C, %A
73*9880d681SAndroid Build Coastguard Worker /// into:
74*9880d681SAndroid Build Coastguard Worker /// %C = select %cond, %B, 0
75*9880d681SAndroid Build Coastguard Worker /// %D = or %A, %C
76*9880d681SAndroid Build Coastguard Worker ///
77*9880d681SAndroid Build Coastguard Worker /// Assuming that the specified instruction is an operand to the select, return
78*9880d681SAndroid Build Coastguard Worker /// a bitmask indicating which operands of this instruction are foldable if they
79*9880d681SAndroid Build Coastguard Worker /// equal the other incoming value of the select.
80*9880d681SAndroid Build Coastguard Worker ///
GetSelectFoldableOperands(Instruction * I)81*9880d681SAndroid Build Coastguard Worker static unsigned GetSelectFoldableOperands(Instruction *I) {
82*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
83*9880d681SAndroid Build Coastguard Worker case Instruction::Add:
84*9880d681SAndroid Build Coastguard Worker case Instruction::Mul:
85*9880d681SAndroid Build Coastguard Worker case Instruction::And:
86*9880d681SAndroid Build Coastguard Worker case Instruction::Or:
87*9880d681SAndroid Build Coastguard Worker case Instruction::Xor:
88*9880d681SAndroid Build Coastguard Worker return 3; // Can fold through either operand.
89*9880d681SAndroid Build Coastguard Worker case Instruction::Sub: // Can only fold on the amount subtracted.
90*9880d681SAndroid Build Coastguard Worker case Instruction::Shl: // Can only fold on the shift amount.
91*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
92*9880d681SAndroid Build Coastguard Worker case Instruction::AShr:
93*9880d681SAndroid Build Coastguard Worker return 1;
94*9880d681SAndroid Build Coastguard Worker default:
95*9880d681SAndroid Build Coastguard Worker return 0; // Cannot fold
96*9880d681SAndroid Build Coastguard Worker }
97*9880d681SAndroid Build Coastguard Worker }
98*9880d681SAndroid Build Coastguard Worker
99*9880d681SAndroid Build Coastguard Worker /// For the same transformation as the previous function, return the identity
100*9880d681SAndroid Build Coastguard Worker /// constant that goes into the select.
GetSelectFoldableConstant(Instruction * I)101*9880d681SAndroid Build Coastguard Worker static Constant *GetSelectFoldableConstant(Instruction *I) {
102*9880d681SAndroid Build Coastguard Worker switch (I->getOpcode()) {
103*9880d681SAndroid Build Coastguard Worker default: llvm_unreachable("This cannot happen!");
104*9880d681SAndroid Build Coastguard Worker case Instruction::Add:
105*9880d681SAndroid Build Coastguard Worker case Instruction::Sub:
106*9880d681SAndroid Build Coastguard Worker case Instruction::Or:
107*9880d681SAndroid Build Coastguard Worker case Instruction::Xor:
108*9880d681SAndroid Build Coastguard Worker case Instruction::Shl:
109*9880d681SAndroid Build Coastguard Worker case Instruction::LShr:
110*9880d681SAndroid Build Coastguard Worker case Instruction::AShr:
111*9880d681SAndroid Build Coastguard Worker return Constant::getNullValue(I->getType());
112*9880d681SAndroid Build Coastguard Worker case Instruction::And:
113*9880d681SAndroid Build Coastguard Worker return Constant::getAllOnesValue(I->getType());
114*9880d681SAndroid Build Coastguard Worker case Instruction::Mul:
115*9880d681SAndroid Build Coastguard Worker return ConstantInt::get(I->getType(), 1);
116*9880d681SAndroid Build Coastguard Worker }
117*9880d681SAndroid Build Coastguard Worker }
118*9880d681SAndroid Build Coastguard Worker
119*9880d681SAndroid Build Coastguard Worker /// We have (select c, TI, FI), and we know that TI and FI have the same opcode.
FoldSelectOpOp(SelectInst & SI,Instruction * TI,Instruction * FI)120*9880d681SAndroid Build Coastguard Worker Instruction *InstCombiner::FoldSelectOpOp(SelectInst &SI, Instruction *TI,
121*9880d681SAndroid Build Coastguard Worker Instruction *FI) {
122*9880d681SAndroid Build Coastguard Worker // If this is a cast from the same type, merge.
123*9880d681SAndroid Build Coastguard Worker if (TI->getNumOperands() == 1 && TI->isCast()) {
124*9880d681SAndroid Build Coastguard Worker Type *FIOpndTy = FI->getOperand(0)->getType();
125*9880d681SAndroid Build Coastguard Worker if (TI->getOperand(0)->getType() != FIOpndTy)
126*9880d681SAndroid Build Coastguard Worker return nullptr;
127*9880d681SAndroid Build Coastguard Worker
128*9880d681SAndroid Build Coastguard Worker // The select condition may be a vector. We may only change the operand
129*9880d681SAndroid Build Coastguard Worker // type if the vector width remains the same (and matches the condition).
130*9880d681SAndroid Build Coastguard Worker Type *CondTy = SI.getCondition()->getType();
131*9880d681SAndroid Build Coastguard Worker if (CondTy->isVectorTy()) {
132*9880d681SAndroid Build Coastguard Worker if (!FIOpndTy->isVectorTy())
133*9880d681SAndroid Build Coastguard Worker return nullptr;
134*9880d681SAndroid Build Coastguard Worker if (CondTy->getVectorNumElements() != FIOpndTy->getVectorNumElements())
135*9880d681SAndroid Build Coastguard Worker return nullptr;
136*9880d681SAndroid Build Coastguard Worker
137*9880d681SAndroid Build Coastguard Worker // TODO: If the backend knew how to deal with casts better, we could
138*9880d681SAndroid Build Coastguard Worker // remove this limitation. For now, there's too much potential to create
139*9880d681SAndroid Build Coastguard Worker // worse codegen by promoting the select ahead of size-altering casts
140*9880d681SAndroid Build Coastguard Worker // (PR28160).
141*9880d681SAndroid Build Coastguard Worker //
142*9880d681SAndroid Build Coastguard Worker // Note that ValueTracking's matchSelectPattern() looks through casts
143*9880d681SAndroid Build Coastguard Worker // without checking 'hasOneUse' when it matches min/max patterns, so this
144*9880d681SAndroid Build Coastguard Worker // transform may end up happening anyway.
145*9880d681SAndroid Build Coastguard Worker if (TI->getOpcode() != Instruction::BitCast &&
146*9880d681SAndroid Build Coastguard Worker (!TI->hasOneUse() || !FI->hasOneUse()))
147*9880d681SAndroid Build Coastguard Worker return nullptr;
148*9880d681SAndroid Build Coastguard Worker
149*9880d681SAndroid Build Coastguard Worker } else if (!TI->hasOneUse() || !FI->hasOneUse()) {
150*9880d681SAndroid Build Coastguard Worker // TODO: The one-use restrictions for a scalar select could be eased if
151*9880d681SAndroid Build Coastguard Worker // the fold of a select in visitLoadInst() was enhanced to match a pattern
152*9880d681SAndroid Build Coastguard Worker // that includes a cast.
153*9880d681SAndroid Build Coastguard Worker return nullptr;
154*9880d681SAndroid Build Coastguard Worker }
155*9880d681SAndroid Build Coastguard Worker
156*9880d681SAndroid Build Coastguard Worker // Fold this by inserting a select from the input values.
157*9880d681SAndroid Build Coastguard Worker Value *NewSI = Builder->CreateSelect(SI.getCondition(), TI->getOperand(0),
158*9880d681SAndroid Build Coastguard Worker FI->getOperand(0), SI.getName()+".v");
159*9880d681SAndroid Build Coastguard Worker return CastInst::Create(Instruction::CastOps(TI->getOpcode()), NewSI,
160*9880d681SAndroid Build Coastguard Worker TI->getType());
161*9880d681SAndroid Build Coastguard Worker }
162*9880d681SAndroid Build Coastguard Worker
163*9880d681SAndroid Build Coastguard Worker // TODO: This function ends awkwardly in unreachable - fix to be more normal.
164*9880d681SAndroid Build Coastguard Worker
165*9880d681SAndroid Build Coastguard Worker // Only handle binary operators with one-use here. As with the cast case
166*9880d681SAndroid Build Coastguard Worker // above, it may be possible to relax the one-use constraint, but that needs
167*9880d681SAndroid Build Coastguard Worker // be examined carefully since it may not reduce the total number of
168*9880d681SAndroid Build Coastguard Worker // instructions.
169*9880d681SAndroid Build Coastguard Worker if (!isa<BinaryOperator>(TI) || !TI->hasOneUse() || !FI->hasOneUse())
170*9880d681SAndroid Build Coastguard Worker return nullptr;
171*9880d681SAndroid Build Coastguard Worker
172*9880d681SAndroid Build Coastguard Worker // Figure out if the operations have any operands in common.
173*9880d681SAndroid Build Coastguard Worker Value *MatchOp, *OtherOpT, *OtherOpF;
174*9880d681SAndroid Build Coastguard Worker bool MatchIsOpZero;
175*9880d681SAndroid Build Coastguard Worker if (TI->getOperand(0) == FI->getOperand(0)) {
176*9880d681SAndroid Build Coastguard Worker MatchOp = TI->getOperand(0);
177*9880d681SAndroid Build Coastguard Worker OtherOpT = TI->getOperand(1);
178*9880d681SAndroid Build Coastguard Worker OtherOpF = FI->getOperand(1);
179*9880d681SAndroid Build Coastguard Worker MatchIsOpZero = true;
180*9880d681SAndroid Build Coastguard Worker } else if (TI->getOperand(1) == FI->getOperand(1)) {
181*9880d681SAndroid Build Coastguard Worker MatchOp = TI->getOperand(1);
182*9880d681SAndroid Build Coastguard Worker OtherOpT = TI->getOperand(0);
183*9880d681SAndroid Build Coastguard Worker OtherOpF = FI->getOperand(0);
184*9880d681SAndroid Build Coastguard Worker MatchIsOpZero = false;
185*9880d681SAndroid Build Coastguard Worker } else if (!TI->isCommutative()) {
186*9880d681SAndroid Build Coastguard Worker return nullptr;
187*9880d681SAndroid Build Coastguard Worker } else if (TI->getOperand(0) == FI->getOperand(1)) {
188*9880d681SAndroid Build Coastguard Worker MatchOp = TI->getOperand(0);
189*9880d681SAndroid Build Coastguard Worker OtherOpT = TI->getOperand(1);
190*9880d681SAndroid Build Coastguard Worker OtherOpF = FI->getOperand(0);
191*9880d681SAndroid Build Coastguard Worker MatchIsOpZero = true;
192*9880d681SAndroid Build Coastguard Worker } else if (TI->getOperand(1) == FI->getOperand(0)) {
193*9880d681SAndroid Build Coastguard Worker MatchOp = TI->getOperand(1);
194*9880d681SAndroid Build Coastguard Worker OtherOpT = TI->getOperand(0);
195*9880d681SAndroid Build Coastguard Worker OtherOpF = FI->getOperand(1);
196*9880d681SAndroid Build Coastguard Worker MatchIsOpZero = true;
197*9880d681SAndroid Build Coastguard Worker } else {
198*9880d681SAndroid Build Coastguard Worker return nullptr;
199*9880d681SAndroid Build Coastguard Worker }
200*9880d681SAndroid Build Coastguard Worker
201*9880d681SAndroid Build Coastguard Worker // If we reach here, they do have operations in common.
202*9880d681SAndroid Build Coastguard Worker Value *NewSI = Builder->CreateSelect(SI.getCondition(), OtherOpT,
203*9880d681SAndroid Build Coastguard Worker OtherOpF, SI.getName()+".v");
204*9880d681SAndroid Build Coastguard Worker
205*9880d681SAndroid Build Coastguard Worker if (BinaryOperator *BO = dyn_cast<BinaryOperator>(TI)) {
206*9880d681SAndroid Build Coastguard Worker if (MatchIsOpZero)
207*9880d681SAndroid Build Coastguard Worker return BinaryOperator::Create(BO->getOpcode(), MatchOp, NewSI);
208*9880d681SAndroid Build Coastguard Worker else
209*9880d681SAndroid Build Coastguard Worker return BinaryOperator::Create(BO->getOpcode(), NewSI, MatchOp);
210*9880d681SAndroid Build Coastguard Worker }
211*9880d681SAndroid Build Coastguard Worker llvm_unreachable("Shouldn't get here");
212*9880d681SAndroid Build Coastguard Worker }
213*9880d681SAndroid Build Coastguard Worker
isSelect01(Constant * C1,Constant * C2)214*9880d681SAndroid Build Coastguard Worker static bool isSelect01(Constant *C1, Constant *C2) {
215*9880d681SAndroid Build Coastguard Worker ConstantInt *C1I = dyn_cast<ConstantInt>(C1);
216*9880d681SAndroid Build Coastguard Worker if (!C1I)
217*9880d681SAndroid Build Coastguard Worker return false;
218*9880d681SAndroid Build Coastguard Worker ConstantInt *C2I = dyn_cast<ConstantInt>(C2);
219*9880d681SAndroid Build Coastguard Worker if (!C2I)
220*9880d681SAndroid Build Coastguard Worker return false;
221*9880d681SAndroid Build Coastguard Worker if (!C1I->isZero() && !C2I->isZero()) // One side must be zero.
222*9880d681SAndroid Build Coastguard Worker return false;
223*9880d681SAndroid Build Coastguard Worker return C1I->isOne() || C1I->isAllOnesValue() ||
224*9880d681SAndroid Build Coastguard Worker C2I->isOne() || C2I->isAllOnesValue();
225*9880d681SAndroid Build Coastguard Worker }
226*9880d681SAndroid Build Coastguard Worker
227*9880d681SAndroid Build Coastguard Worker /// Try to fold the select into one of the operands to allow further
228*9880d681SAndroid Build Coastguard Worker /// optimization.
FoldSelectIntoOp(SelectInst & SI,Value * TrueVal,Value * FalseVal)229*9880d681SAndroid Build Coastguard Worker Instruction *InstCombiner::FoldSelectIntoOp(SelectInst &SI, Value *TrueVal,
230*9880d681SAndroid Build Coastguard Worker Value *FalseVal) {
231*9880d681SAndroid Build Coastguard Worker // See the comment above GetSelectFoldableOperands for a description of the
232*9880d681SAndroid Build Coastguard Worker // transformation we are doing here.
233*9880d681SAndroid Build Coastguard Worker if (Instruction *TVI = dyn_cast<Instruction>(TrueVal)) {
234*9880d681SAndroid Build Coastguard Worker if (TVI->hasOneUse() && TVI->getNumOperands() == 2 &&
235*9880d681SAndroid Build Coastguard Worker !isa<Constant>(FalseVal)) {
236*9880d681SAndroid Build Coastguard Worker if (unsigned SFO = GetSelectFoldableOperands(TVI)) {
237*9880d681SAndroid Build Coastguard Worker unsigned OpToFold = 0;
238*9880d681SAndroid Build Coastguard Worker if ((SFO & 1) && FalseVal == TVI->getOperand(0)) {
239*9880d681SAndroid Build Coastguard Worker OpToFold = 1;
240*9880d681SAndroid Build Coastguard Worker } else if ((SFO & 2) && FalseVal == TVI->getOperand(1)) {
241*9880d681SAndroid Build Coastguard Worker OpToFold = 2;
242*9880d681SAndroid Build Coastguard Worker }
243*9880d681SAndroid Build Coastguard Worker
244*9880d681SAndroid Build Coastguard Worker if (OpToFold) {
245*9880d681SAndroid Build Coastguard Worker Constant *C = GetSelectFoldableConstant(TVI);
246*9880d681SAndroid Build Coastguard Worker Value *OOp = TVI->getOperand(2-OpToFold);
247*9880d681SAndroid Build Coastguard Worker // Avoid creating select between 2 constants unless it's selecting
248*9880d681SAndroid Build Coastguard Worker // between 0, 1 and -1.
249*9880d681SAndroid Build Coastguard Worker if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) {
250*9880d681SAndroid Build Coastguard Worker Value *NewSel = Builder->CreateSelect(SI.getCondition(), OOp, C);
251*9880d681SAndroid Build Coastguard Worker NewSel->takeName(TVI);
252*9880d681SAndroid Build Coastguard Worker BinaryOperator *TVI_BO = cast<BinaryOperator>(TVI);
253*9880d681SAndroid Build Coastguard Worker BinaryOperator *BO = BinaryOperator::Create(TVI_BO->getOpcode(),
254*9880d681SAndroid Build Coastguard Worker FalseVal, NewSel);
255*9880d681SAndroid Build Coastguard Worker BO->copyIRFlags(TVI_BO);
256*9880d681SAndroid Build Coastguard Worker return BO;
257*9880d681SAndroid Build Coastguard Worker }
258*9880d681SAndroid Build Coastguard Worker }
259*9880d681SAndroid Build Coastguard Worker }
260*9880d681SAndroid Build Coastguard Worker }
261*9880d681SAndroid Build Coastguard Worker }
262*9880d681SAndroid Build Coastguard Worker
263*9880d681SAndroid Build Coastguard Worker if (Instruction *FVI = dyn_cast<Instruction>(FalseVal)) {
264*9880d681SAndroid Build Coastguard Worker if (FVI->hasOneUse() && FVI->getNumOperands() == 2 &&
265*9880d681SAndroid Build Coastguard Worker !isa<Constant>(TrueVal)) {
266*9880d681SAndroid Build Coastguard Worker if (unsigned SFO = GetSelectFoldableOperands(FVI)) {
267*9880d681SAndroid Build Coastguard Worker unsigned OpToFold = 0;
268*9880d681SAndroid Build Coastguard Worker if ((SFO & 1) && TrueVal == FVI->getOperand(0)) {
269*9880d681SAndroid Build Coastguard Worker OpToFold = 1;
270*9880d681SAndroid Build Coastguard Worker } else if ((SFO & 2) && TrueVal == FVI->getOperand(1)) {
271*9880d681SAndroid Build Coastguard Worker OpToFold = 2;
272*9880d681SAndroid Build Coastguard Worker }
273*9880d681SAndroid Build Coastguard Worker
274*9880d681SAndroid Build Coastguard Worker if (OpToFold) {
275*9880d681SAndroid Build Coastguard Worker Constant *C = GetSelectFoldableConstant(FVI);
276*9880d681SAndroid Build Coastguard Worker Value *OOp = FVI->getOperand(2-OpToFold);
277*9880d681SAndroid Build Coastguard Worker // Avoid creating select between 2 constants unless it's selecting
278*9880d681SAndroid Build Coastguard Worker // between 0, 1 and -1.
279*9880d681SAndroid Build Coastguard Worker if (!isa<Constant>(OOp) || isSelect01(C, cast<Constant>(OOp))) {
280*9880d681SAndroid Build Coastguard Worker Value *NewSel = Builder->CreateSelect(SI.getCondition(), C, OOp);
281*9880d681SAndroid Build Coastguard Worker NewSel->takeName(FVI);
282*9880d681SAndroid Build Coastguard Worker BinaryOperator *FVI_BO = cast<BinaryOperator>(FVI);
283*9880d681SAndroid Build Coastguard Worker BinaryOperator *BO = BinaryOperator::Create(FVI_BO->getOpcode(),
284*9880d681SAndroid Build Coastguard Worker TrueVal, NewSel);
285*9880d681SAndroid Build Coastguard Worker BO->copyIRFlags(FVI_BO);
286*9880d681SAndroid Build Coastguard Worker return BO;
287*9880d681SAndroid Build Coastguard Worker }
288*9880d681SAndroid Build Coastguard Worker }
289*9880d681SAndroid Build Coastguard Worker }
290*9880d681SAndroid Build Coastguard Worker }
291*9880d681SAndroid Build Coastguard Worker }
292*9880d681SAndroid Build Coastguard Worker
293*9880d681SAndroid Build Coastguard Worker return nullptr;
294*9880d681SAndroid Build Coastguard Worker }
295*9880d681SAndroid Build Coastguard Worker
296*9880d681SAndroid Build Coastguard Worker /// We want to turn:
297*9880d681SAndroid Build Coastguard Worker /// (select (icmp eq (and X, C1), 0), Y, (or Y, C2))
298*9880d681SAndroid Build Coastguard Worker /// into:
299*9880d681SAndroid Build Coastguard Worker /// (or (shl (and X, C1), C3), y)
300*9880d681SAndroid Build Coastguard Worker /// iff:
301*9880d681SAndroid Build Coastguard Worker /// C1 and C2 are both powers of 2
302*9880d681SAndroid Build Coastguard Worker /// where:
303*9880d681SAndroid Build Coastguard Worker /// C3 = Log(C2) - Log(C1)
304*9880d681SAndroid Build Coastguard Worker ///
305*9880d681SAndroid Build Coastguard Worker /// This transform handles cases where:
306*9880d681SAndroid Build Coastguard Worker /// 1. The icmp predicate is inverted
307*9880d681SAndroid Build Coastguard Worker /// 2. The select operands are reversed
308*9880d681SAndroid Build Coastguard Worker /// 3. The magnitude of C2 and C1 are flipped
foldSelectICmpAndOr(const SelectInst & SI,Value * TrueVal,Value * FalseVal,InstCombiner::BuilderTy * Builder)309*9880d681SAndroid Build Coastguard Worker static Value *foldSelectICmpAndOr(const SelectInst &SI, Value *TrueVal,
310*9880d681SAndroid Build Coastguard Worker Value *FalseVal,
311*9880d681SAndroid Build Coastguard Worker InstCombiner::BuilderTy *Builder) {
312*9880d681SAndroid Build Coastguard Worker const ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition());
313*9880d681SAndroid Build Coastguard Worker if (!IC || !IC->isEquality() || !SI.getType()->isIntegerTy())
314*9880d681SAndroid Build Coastguard Worker return nullptr;
315*9880d681SAndroid Build Coastguard Worker
316*9880d681SAndroid Build Coastguard Worker Value *CmpLHS = IC->getOperand(0);
317*9880d681SAndroid Build Coastguard Worker Value *CmpRHS = IC->getOperand(1);
318*9880d681SAndroid Build Coastguard Worker
319*9880d681SAndroid Build Coastguard Worker if (!match(CmpRHS, m_Zero()))
320*9880d681SAndroid Build Coastguard Worker return nullptr;
321*9880d681SAndroid Build Coastguard Worker
322*9880d681SAndroid Build Coastguard Worker Value *X;
323*9880d681SAndroid Build Coastguard Worker const APInt *C1;
324*9880d681SAndroid Build Coastguard Worker if (!match(CmpLHS, m_And(m_Value(X), m_Power2(C1))))
325*9880d681SAndroid Build Coastguard Worker return nullptr;
326*9880d681SAndroid Build Coastguard Worker
327*9880d681SAndroid Build Coastguard Worker const APInt *C2;
328*9880d681SAndroid Build Coastguard Worker bool OrOnTrueVal = false;
329*9880d681SAndroid Build Coastguard Worker bool OrOnFalseVal = match(FalseVal, m_Or(m_Specific(TrueVal), m_Power2(C2)));
330*9880d681SAndroid Build Coastguard Worker if (!OrOnFalseVal)
331*9880d681SAndroid Build Coastguard Worker OrOnTrueVal = match(TrueVal, m_Or(m_Specific(FalseVal), m_Power2(C2)));
332*9880d681SAndroid Build Coastguard Worker
333*9880d681SAndroid Build Coastguard Worker if (!OrOnFalseVal && !OrOnTrueVal)
334*9880d681SAndroid Build Coastguard Worker return nullptr;
335*9880d681SAndroid Build Coastguard Worker
336*9880d681SAndroid Build Coastguard Worker Value *V = CmpLHS;
337*9880d681SAndroid Build Coastguard Worker Value *Y = OrOnFalseVal ? TrueVal : FalseVal;
338*9880d681SAndroid Build Coastguard Worker
339*9880d681SAndroid Build Coastguard Worker unsigned C1Log = C1->logBase2();
340*9880d681SAndroid Build Coastguard Worker unsigned C2Log = C2->logBase2();
341*9880d681SAndroid Build Coastguard Worker if (C2Log > C1Log) {
342*9880d681SAndroid Build Coastguard Worker V = Builder->CreateZExtOrTrunc(V, Y->getType());
343*9880d681SAndroid Build Coastguard Worker V = Builder->CreateShl(V, C2Log - C1Log);
344*9880d681SAndroid Build Coastguard Worker } else if (C1Log > C2Log) {
345*9880d681SAndroid Build Coastguard Worker V = Builder->CreateLShr(V, C1Log - C2Log);
346*9880d681SAndroid Build Coastguard Worker V = Builder->CreateZExtOrTrunc(V, Y->getType());
347*9880d681SAndroid Build Coastguard Worker } else
348*9880d681SAndroid Build Coastguard Worker V = Builder->CreateZExtOrTrunc(V, Y->getType());
349*9880d681SAndroid Build Coastguard Worker
350*9880d681SAndroid Build Coastguard Worker ICmpInst::Predicate Pred = IC->getPredicate();
351*9880d681SAndroid Build Coastguard Worker if ((Pred == ICmpInst::ICMP_NE && OrOnFalseVal) ||
352*9880d681SAndroid Build Coastguard Worker (Pred == ICmpInst::ICMP_EQ && OrOnTrueVal))
353*9880d681SAndroid Build Coastguard Worker V = Builder->CreateXor(V, *C2);
354*9880d681SAndroid Build Coastguard Worker
355*9880d681SAndroid Build Coastguard Worker return Builder->CreateOr(V, Y);
356*9880d681SAndroid Build Coastguard Worker }
357*9880d681SAndroid Build Coastguard Worker
358*9880d681SAndroid Build Coastguard Worker /// Attempt to fold a cttz/ctlz followed by a icmp plus select into a single
359*9880d681SAndroid Build Coastguard Worker /// call to cttz/ctlz with flag 'is_zero_undef' cleared.
360*9880d681SAndroid Build Coastguard Worker ///
361*9880d681SAndroid Build Coastguard Worker /// For example, we can fold the following code sequence:
362*9880d681SAndroid Build Coastguard Worker /// \code
363*9880d681SAndroid Build Coastguard Worker /// %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 true)
364*9880d681SAndroid Build Coastguard Worker /// %1 = icmp ne i32 %x, 0
365*9880d681SAndroid Build Coastguard Worker /// %2 = select i1 %1, i32 %0, i32 32
366*9880d681SAndroid Build Coastguard Worker /// \code
367*9880d681SAndroid Build Coastguard Worker ///
368*9880d681SAndroid Build Coastguard Worker /// into:
369*9880d681SAndroid Build Coastguard Worker /// %0 = tail call i32 @llvm.cttz.i32(i32 %x, i1 false)
foldSelectCttzCtlz(ICmpInst * ICI,Value * TrueVal,Value * FalseVal,InstCombiner::BuilderTy * Builder)370*9880d681SAndroid Build Coastguard Worker static Value *foldSelectCttzCtlz(ICmpInst *ICI, Value *TrueVal, Value *FalseVal,
371*9880d681SAndroid Build Coastguard Worker InstCombiner::BuilderTy *Builder) {
372*9880d681SAndroid Build Coastguard Worker ICmpInst::Predicate Pred = ICI->getPredicate();
373*9880d681SAndroid Build Coastguard Worker Value *CmpLHS = ICI->getOperand(0);
374*9880d681SAndroid Build Coastguard Worker Value *CmpRHS = ICI->getOperand(1);
375*9880d681SAndroid Build Coastguard Worker
376*9880d681SAndroid Build Coastguard Worker // Check if the condition value compares a value for equality against zero.
377*9880d681SAndroid Build Coastguard Worker if (!ICI->isEquality() || !match(CmpRHS, m_Zero()))
378*9880d681SAndroid Build Coastguard Worker return nullptr;
379*9880d681SAndroid Build Coastguard Worker
380*9880d681SAndroid Build Coastguard Worker Value *Count = FalseVal;
381*9880d681SAndroid Build Coastguard Worker Value *ValueOnZero = TrueVal;
382*9880d681SAndroid Build Coastguard Worker if (Pred == ICmpInst::ICMP_NE)
383*9880d681SAndroid Build Coastguard Worker std::swap(Count, ValueOnZero);
384*9880d681SAndroid Build Coastguard Worker
385*9880d681SAndroid Build Coastguard Worker // Skip zero extend/truncate.
386*9880d681SAndroid Build Coastguard Worker Value *V = nullptr;
387*9880d681SAndroid Build Coastguard Worker if (match(Count, m_ZExt(m_Value(V))) ||
388*9880d681SAndroid Build Coastguard Worker match(Count, m_Trunc(m_Value(V))))
389*9880d681SAndroid Build Coastguard Worker Count = V;
390*9880d681SAndroid Build Coastguard Worker
391*9880d681SAndroid Build Coastguard Worker // Check if the value propagated on zero is a constant number equal to the
392*9880d681SAndroid Build Coastguard Worker // sizeof in bits of 'Count'.
393*9880d681SAndroid Build Coastguard Worker unsigned SizeOfInBits = Count->getType()->getScalarSizeInBits();
394*9880d681SAndroid Build Coastguard Worker if (!match(ValueOnZero, m_SpecificInt(SizeOfInBits)))
395*9880d681SAndroid Build Coastguard Worker return nullptr;
396*9880d681SAndroid Build Coastguard Worker
397*9880d681SAndroid Build Coastguard Worker // Check that 'Count' is a call to intrinsic cttz/ctlz. Also check that the
398*9880d681SAndroid Build Coastguard Worker // input to the cttz/ctlz is used as LHS for the compare instruction.
399*9880d681SAndroid Build Coastguard Worker if (match(Count, m_Intrinsic<Intrinsic::cttz>(m_Specific(CmpLHS))) ||
400*9880d681SAndroid Build Coastguard Worker match(Count, m_Intrinsic<Intrinsic::ctlz>(m_Specific(CmpLHS)))) {
401*9880d681SAndroid Build Coastguard Worker IntrinsicInst *II = cast<IntrinsicInst>(Count);
402*9880d681SAndroid Build Coastguard Worker IRBuilder<> Builder(II);
403*9880d681SAndroid Build Coastguard Worker // Explicitly clear the 'undef_on_zero' flag.
404*9880d681SAndroid Build Coastguard Worker IntrinsicInst *NewI = cast<IntrinsicInst>(II->clone());
405*9880d681SAndroid Build Coastguard Worker Type *Ty = NewI->getArgOperand(1)->getType();
406*9880d681SAndroid Build Coastguard Worker NewI->setArgOperand(1, Constant::getNullValue(Ty));
407*9880d681SAndroid Build Coastguard Worker Builder.Insert(NewI);
408*9880d681SAndroid Build Coastguard Worker return Builder.CreateZExtOrTrunc(NewI, ValueOnZero->getType());
409*9880d681SAndroid Build Coastguard Worker }
410*9880d681SAndroid Build Coastguard Worker
411*9880d681SAndroid Build Coastguard Worker return nullptr;
412*9880d681SAndroid Build Coastguard Worker }
413*9880d681SAndroid Build Coastguard Worker
414*9880d681SAndroid Build Coastguard Worker /// Visit a SelectInst that has an ICmpInst as its first operand.
visitSelectInstWithICmp(SelectInst & SI,ICmpInst * ICI)415*9880d681SAndroid Build Coastguard Worker Instruction *InstCombiner::visitSelectInstWithICmp(SelectInst &SI,
416*9880d681SAndroid Build Coastguard Worker ICmpInst *ICI) {
417*9880d681SAndroid Build Coastguard Worker bool Changed = false;
418*9880d681SAndroid Build Coastguard Worker ICmpInst::Predicate Pred = ICI->getPredicate();
419*9880d681SAndroid Build Coastguard Worker Value *CmpLHS = ICI->getOperand(0);
420*9880d681SAndroid Build Coastguard Worker Value *CmpRHS = ICI->getOperand(1);
421*9880d681SAndroid Build Coastguard Worker Value *TrueVal = SI.getTrueValue();
422*9880d681SAndroid Build Coastguard Worker Value *FalseVal = SI.getFalseValue();
423*9880d681SAndroid Build Coastguard Worker
424*9880d681SAndroid Build Coastguard Worker // Check cases where the comparison is with a constant that
425*9880d681SAndroid Build Coastguard Worker // can be adjusted to fit the min/max idiom. We may move or edit ICI
426*9880d681SAndroid Build Coastguard Worker // here, so make sure the select is the only user.
427*9880d681SAndroid Build Coastguard Worker if (ICI->hasOneUse())
428*9880d681SAndroid Build Coastguard Worker if (ConstantInt *CI = dyn_cast<ConstantInt>(CmpRHS)) {
429*9880d681SAndroid Build Coastguard Worker switch (Pred) {
430*9880d681SAndroid Build Coastguard Worker default: break;
431*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_ULT:
432*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SLT:
433*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_UGT:
434*9880d681SAndroid Build Coastguard Worker case ICmpInst::ICMP_SGT: {
435*9880d681SAndroid Build Coastguard Worker // These transformations only work for selects over integers.
436*9880d681SAndroid Build Coastguard Worker IntegerType *SelectTy = dyn_cast<IntegerType>(SI.getType());
437*9880d681SAndroid Build Coastguard Worker if (!SelectTy)
438*9880d681SAndroid Build Coastguard Worker break;
439*9880d681SAndroid Build Coastguard Worker
440*9880d681SAndroid Build Coastguard Worker Constant *AdjustedRHS;
441*9880d681SAndroid Build Coastguard Worker if (Pred == ICmpInst::ICMP_UGT || Pred == ICmpInst::ICMP_SGT)
442*9880d681SAndroid Build Coastguard Worker AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() + 1);
443*9880d681SAndroid Build Coastguard Worker else // (Pred == ICmpInst::ICMP_ULT || Pred == ICmpInst::ICMP_SLT)
444*9880d681SAndroid Build Coastguard Worker AdjustedRHS = ConstantInt::get(CI->getContext(), CI->getValue() - 1);
445*9880d681SAndroid Build Coastguard Worker
446*9880d681SAndroid Build Coastguard Worker // X > C ? X : C+1 --> X < C+1 ? C+1 : X
447*9880d681SAndroid Build Coastguard Worker // X < C ? X : C-1 --> X > C-1 ? C-1 : X
448*9880d681SAndroid Build Coastguard Worker if ((CmpLHS == TrueVal && AdjustedRHS == FalseVal) ||
449*9880d681SAndroid Build Coastguard Worker (CmpLHS == FalseVal && AdjustedRHS == TrueVal))
450*9880d681SAndroid Build Coastguard Worker ; // Nothing to do here. Values match without any sign/zero extension.
451*9880d681SAndroid Build Coastguard Worker
452*9880d681SAndroid Build Coastguard Worker // Types do not match. Instead of calculating this with mixed types
453*9880d681SAndroid Build Coastguard Worker // promote all to the larger type. This enables scalar evolution to
454*9880d681SAndroid Build Coastguard Worker // analyze this expression.
455*9880d681SAndroid Build Coastguard Worker else if (CmpRHS->getType()->getScalarSizeInBits()
456*9880d681SAndroid Build Coastguard Worker < SelectTy->getBitWidth()) {
457*9880d681SAndroid Build Coastguard Worker Constant *sextRHS = ConstantExpr::getSExt(AdjustedRHS, SelectTy);
458*9880d681SAndroid Build Coastguard Worker
459*9880d681SAndroid Build Coastguard Worker // X = sext x; x >s c ? X : C+1 --> X = sext x; X <s C+1 ? C+1 : X
460*9880d681SAndroid Build Coastguard Worker // X = sext x; x <s c ? X : C-1 --> X = sext x; X >s C-1 ? C-1 : X
461*9880d681SAndroid Build Coastguard Worker // X = sext x; x >u c ? X : C+1 --> X = sext x; X <u C+1 ? C+1 : X
462*9880d681SAndroid Build Coastguard Worker // X = sext x; x <u c ? X : C-1 --> X = sext x; X >u C-1 ? C-1 : X
463*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_SExt(m_Specific(CmpLHS))) &&
464*9880d681SAndroid Build Coastguard Worker sextRHS == FalseVal) {
465*9880d681SAndroid Build Coastguard Worker CmpLHS = TrueVal;
466*9880d681SAndroid Build Coastguard Worker AdjustedRHS = sextRHS;
467*9880d681SAndroid Build Coastguard Worker } else if (match(FalseVal, m_SExt(m_Specific(CmpLHS))) &&
468*9880d681SAndroid Build Coastguard Worker sextRHS == TrueVal) {
469*9880d681SAndroid Build Coastguard Worker CmpLHS = FalseVal;
470*9880d681SAndroid Build Coastguard Worker AdjustedRHS = sextRHS;
471*9880d681SAndroid Build Coastguard Worker } else if (ICI->isUnsigned()) {
472*9880d681SAndroid Build Coastguard Worker Constant *zextRHS = ConstantExpr::getZExt(AdjustedRHS, SelectTy);
473*9880d681SAndroid Build Coastguard Worker // X = zext x; x >u c ? X : C+1 --> X = zext x; X <u C+1 ? C+1 : X
474*9880d681SAndroid Build Coastguard Worker // X = zext x; x <u c ? X : C-1 --> X = zext x; X >u C-1 ? C-1 : X
475*9880d681SAndroid Build Coastguard Worker // zext + signed compare cannot be changed:
476*9880d681SAndroid Build Coastguard Worker // 0xff <s 0x00, but 0x00ff >s 0x0000
477*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_ZExt(m_Specific(CmpLHS))) &&
478*9880d681SAndroid Build Coastguard Worker zextRHS == FalseVal) {
479*9880d681SAndroid Build Coastguard Worker CmpLHS = TrueVal;
480*9880d681SAndroid Build Coastguard Worker AdjustedRHS = zextRHS;
481*9880d681SAndroid Build Coastguard Worker } else if (match(FalseVal, m_ZExt(m_Specific(CmpLHS))) &&
482*9880d681SAndroid Build Coastguard Worker zextRHS == TrueVal) {
483*9880d681SAndroid Build Coastguard Worker CmpLHS = FalseVal;
484*9880d681SAndroid Build Coastguard Worker AdjustedRHS = zextRHS;
485*9880d681SAndroid Build Coastguard Worker } else
486*9880d681SAndroid Build Coastguard Worker break;
487*9880d681SAndroid Build Coastguard Worker } else
488*9880d681SAndroid Build Coastguard Worker break;
489*9880d681SAndroid Build Coastguard Worker } else
490*9880d681SAndroid Build Coastguard Worker break;
491*9880d681SAndroid Build Coastguard Worker
492*9880d681SAndroid Build Coastguard Worker Pred = ICmpInst::getSwappedPredicate(Pred);
493*9880d681SAndroid Build Coastguard Worker CmpRHS = AdjustedRHS;
494*9880d681SAndroid Build Coastguard Worker std::swap(FalseVal, TrueVal);
495*9880d681SAndroid Build Coastguard Worker ICI->setPredicate(Pred);
496*9880d681SAndroid Build Coastguard Worker ICI->setOperand(0, CmpLHS);
497*9880d681SAndroid Build Coastguard Worker ICI->setOperand(1, CmpRHS);
498*9880d681SAndroid Build Coastguard Worker SI.setOperand(1, TrueVal);
499*9880d681SAndroid Build Coastguard Worker SI.setOperand(2, FalseVal);
500*9880d681SAndroid Build Coastguard Worker
501*9880d681SAndroid Build Coastguard Worker // Move ICI instruction right before the select instruction. Otherwise
502*9880d681SAndroid Build Coastguard Worker // the sext/zext value may be defined after the ICI instruction uses it.
503*9880d681SAndroid Build Coastguard Worker ICI->moveBefore(&SI);
504*9880d681SAndroid Build Coastguard Worker
505*9880d681SAndroid Build Coastguard Worker Changed = true;
506*9880d681SAndroid Build Coastguard Worker break;
507*9880d681SAndroid Build Coastguard Worker }
508*9880d681SAndroid Build Coastguard Worker }
509*9880d681SAndroid Build Coastguard Worker }
510*9880d681SAndroid Build Coastguard Worker
511*9880d681SAndroid Build Coastguard Worker // Transform (X >s -1) ? C1 : C2 --> ((X >>s 31) & (C2 - C1)) + C1
512*9880d681SAndroid Build Coastguard Worker // and (X <s 0) ? C2 : C1 --> ((X >>s 31) & (C2 - C1)) + C1
513*9880d681SAndroid Build Coastguard Worker // FIXME: Type and constness constraints could be lifted, but we have to
514*9880d681SAndroid Build Coastguard Worker // watch code size carefully. We should consider xor instead of
515*9880d681SAndroid Build Coastguard Worker // sub/add when we decide to do that.
516*9880d681SAndroid Build Coastguard Worker if (IntegerType *Ty = dyn_cast<IntegerType>(CmpLHS->getType())) {
517*9880d681SAndroid Build Coastguard Worker if (TrueVal->getType() == Ty) {
518*9880d681SAndroid Build Coastguard Worker if (ConstantInt *Cmp = dyn_cast<ConstantInt>(CmpRHS)) {
519*9880d681SAndroid Build Coastguard Worker ConstantInt *C1 = nullptr, *C2 = nullptr;
520*9880d681SAndroid Build Coastguard Worker if (Pred == ICmpInst::ICMP_SGT && Cmp->isAllOnesValue()) {
521*9880d681SAndroid Build Coastguard Worker C1 = dyn_cast<ConstantInt>(TrueVal);
522*9880d681SAndroid Build Coastguard Worker C2 = dyn_cast<ConstantInt>(FalseVal);
523*9880d681SAndroid Build Coastguard Worker } else if (Pred == ICmpInst::ICMP_SLT && Cmp->isNullValue()) {
524*9880d681SAndroid Build Coastguard Worker C1 = dyn_cast<ConstantInt>(FalseVal);
525*9880d681SAndroid Build Coastguard Worker C2 = dyn_cast<ConstantInt>(TrueVal);
526*9880d681SAndroid Build Coastguard Worker }
527*9880d681SAndroid Build Coastguard Worker if (C1 && C2) {
528*9880d681SAndroid Build Coastguard Worker // This shift results in either -1 or 0.
529*9880d681SAndroid Build Coastguard Worker Value *AShr = Builder->CreateAShr(CmpLHS, Ty->getBitWidth()-1);
530*9880d681SAndroid Build Coastguard Worker
531*9880d681SAndroid Build Coastguard Worker // Check if we can express the operation with a single or.
532*9880d681SAndroid Build Coastguard Worker if (C2->isAllOnesValue())
533*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, Builder->CreateOr(AShr, C1));
534*9880d681SAndroid Build Coastguard Worker
535*9880d681SAndroid Build Coastguard Worker Value *And = Builder->CreateAnd(AShr, C2->getValue()-C1->getValue());
536*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, Builder->CreateAdd(And, C1));
537*9880d681SAndroid Build Coastguard Worker }
538*9880d681SAndroid Build Coastguard Worker }
539*9880d681SAndroid Build Coastguard Worker }
540*9880d681SAndroid Build Coastguard Worker }
541*9880d681SAndroid Build Coastguard Worker
542*9880d681SAndroid Build Coastguard Worker // NOTE: if we wanted to, this is where to detect integer MIN/MAX
543*9880d681SAndroid Build Coastguard Worker
544*9880d681SAndroid Build Coastguard Worker if (CmpRHS != CmpLHS && isa<Constant>(CmpRHS)) {
545*9880d681SAndroid Build Coastguard Worker if (CmpLHS == TrueVal && Pred == ICmpInst::ICMP_EQ) {
546*9880d681SAndroid Build Coastguard Worker // Transform (X == C) ? X : Y -> (X == C) ? C : Y
547*9880d681SAndroid Build Coastguard Worker SI.setOperand(1, CmpRHS);
548*9880d681SAndroid Build Coastguard Worker Changed = true;
549*9880d681SAndroid Build Coastguard Worker } else if (CmpLHS == FalseVal && Pred == ICmpInst::ICMP_NE) {
550*9880d681SAndroid Build Coastguard Worker // Transform (X != C) ? Y : X -> (X != C) ? Y : C
551*9880d681SAndroid Build Coastguard Worker SI.setOperand(2, CmpRHS);
552*9880d681SAndroid Build Coastguard Worker Changed = true;
553*9880d681SAndroid Build Coastguard Worker }
554*9880d681SAndroid Build Coastguard Worker }
555*9880d681SAndroid Build Coastguard Worker
556*9880d681SAndroid Build Coastguard Worker {
557*9880d681SAndroid Build Coastguard Worker unsigned BitWidth = DL.getTypeSizeInBits(TrueVal->getType());
558*9880d681SAndroid Build Coastguard Worker APInt MinSignedValue = APInt::getSignBit(BitWidth);
559*9880d681SAndroid Build Coastguard Worker Value *X;
560*9880d681SAndroid Build Coastguard Worker const APInt *Y, *C;
561*9880d681SAndroid Build Coastguard Worker bool TrueWhenUnset;
562*9880d681SAndroid Build Coastguard Worker bool IsBitTest = false;
563*9880d681SAndroid Build Coastguard Worker if (ICmpInst::isEquality(Pred) &&
564*9880d681SAndroid Build Coastguard Worker match(CmpLHS, m_And(m_Value(X), m_Power2(Y))) &&
565*9880d681SAndroid Build Coastguard Worker match(CmpRHS, m_Zero())) {
566*9880d681SAndroid Build Coastguard Worker IsBitTest = true;
567*9880d681SAndroid Build Coastguard Worker TrueWhenUnset = Pred == ICmpInst::ICMP_EQ;
568*9880d681SAndroid Build Coastguard Worker } else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) {
569*9880d681SAndroid Build Coastguard Worker X = CmpLHS;
570*9880d681SAndroid Build Coastguard Worker Y = &MinSignedValue;
571*9880d681SAndroid Build Coastguard Worker IsBitTest = true;
572*9880d681SAndroid Build Coastguard Worker TrueWhenUnset = false;
573*9880d681SAndroid Build Coastguard Worker } else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) {
574*9880d681SAndroid Build Coastguard Worker X = CmpLHS;
575*9880d681SAndroid Build Coastguard Worker Y = &MinSignedValue;
576*9880d681SAndroid Build Coastguard Worker IsBitTest = true;
577*9880d681SAndroid Build Coastguard Worker TrueWhenUnset = true;
578*9880d681SAndroid Build Coastguard Worker }
579*9880d681SAndroid Build Coastguard Worker if (IsBitTest) {
580*9880d681SAndroid Build Coastguard Worker Value *V = nullptr;
581*9880d681SAndroid Build Coastguard Worker // (X & Y) == 0 ? X : X ^ Y --> X & ~Y
582*9880d681SAndroid Build Coastguard Worker if (TrueWhenUnset && TrueVal == X &&
583*9880d681SAndroid Build Coastguard Worker match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
584*9880d681SAndroid Build Coastguard Worker V = Builder->CreateAnd(X, ~(*Y));
585*9880d681SAndroid Build Coastguard Worker // (X & Y) != 0 ? X ^ Y : X --> X & ~Y
586*9880d681SAndroid Build Coastguard Worker else if (!TrueWhenUnset && FalseVal == X &&
587*9880d681SAndroid Build Coastguard Worker match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
588*9880d681SAndroid Build Coastguard Worker V = Builder->CreateAnd(X, ~(*Y));
589*9880d681SAndroid Build Coastguard Worker // (X & Y) == 0 ? X ^ Y : X --> X | Y
590*9880d681SAndroid Build Coastguard Worker else if (TrueWhenUnset && FalseVal == X &&
591*9880d681SAndroid Build Coastguard Worker match(TrueVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
592*9880d681SAndroid Build Coastguard Worker V = Builder->CreateOr(X, *Y);
593*9880d681SAndroid Build Coastguard Worker // (X & Y) != 0 ? X : X ^ Y --> X | Y
594*9880d681SAndroid Build Coastguard Worker else if (!TrueWhenUnset && TrueVal == X &&
595*9880d681SAndroid Build Coastguard Worker match(FalseVal, m_Xor(m_Specific(X), m_APInt(C))) && *Y == *C)
596*9880d681SAndroid Build Coastguard Worker V = Builder->CreateOr(X, *Y);
597*9880d681SAndroid Build Coastguard Worker
598*9880d681SAndroid Build Coastguard Worker if (V)
599*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
600*9880d681SAndroid Build Coastguard Worker }
601*9880d681SAndroid Build Coastguard Worker }
602*9880d681SAndroid Build Coastguard Worker
603*9880d681SAndroid Build Coastguard Worker if (Value *V = foldSelectICmpAndOr(SI, TrueVal, FalseVal, Builder))
604*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
605*9880d681SAndroid Build Coastguard Worker
606*9880d681SAndroid Build Coastguard Worker if (Value *V = foldSelectCttzCtlz(ICI, TrueVal, FalseVal, Builder))
607*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
608*9880d681SAndroid Build Coastguard Worker
609*9880d681SAndroid Build Coastguard Worker return Changed ? &SI : nullptr;
610*9880d681SAndroid Build Coastguard Worker }
611*9880d681SAndroid Build Coastguard Worker
612*9880d681SAndroid Build Coastguard Worker
613*9880d681SAndroid Build Coastguard Worker /// SI is a select whose condition is a PHI node (but the two may be in
614*9880d681SAndroid Build Coastguard Worker /// different blocks). See if the true/false values (V) are live in all of the
615*9880d681SAndroid Build Coastguard Worker /// predecessor blocks of the PHI. For example, cases like this can't be mapped:
616*9880d681SAndroid Build Coastguard Worker ///
617*9880d681SAndroid Build Coastguard Worker /// X = phi [ C1, BB1], [C2, BB2]
618*9880d681SAndroid Build Coastguard Worker /// Y = add
619*9880d681SAndroid Build Coastguard Worker /// Z = select X, Y, 0
620*9880d681SAndroid Build Coastguard Worker ///
621*9880d681SAndroid Build Coastguard Worker /// because Y is not live in BB1/BB2.
622*9880d681SAndroid Build Coastguard Worker ///
CanSelectOperandBeMappingIntoPredBlock(const Value * V,const SelectInst & SI)623*9880d681SAndroid Build Coastguard Worker static bool CanSelectOperandBeMappingIntoPredBlock(const Value *V,
624*9880d681SAndroid Build Coastguard Worker const SelectInst &SI) {
625*9880d681SAndroid Build Coastguard Worker // If the value is a non-instruction value like a constant or argument, it
626*9880d681SAndroid Build Coastguard Worker // can always be mapped.
627*9880d681SAndroid Build Coastguard Worker const Instruction *I = dyn_cast<Instruction>(V);
628*9880d681SAndroid Build Coastguard Worker if (!I) return true;
629*9880d681SAndroid Build Coastguard Worker
630*9880d681SAndroid Build Coastguard Worker // If V is a PHI node defined in the same block as the condition PHI, we can
631*9880d681SAndroid Build Coastguard Worker // map the arguments.
632*9880d681SAndroid Build Coastguard Worker const PHINode *CondPHI = cast<PHINode>(SI.getCondition());
633*9880d681SAndroid Build Coastguard Worker
634*9880d681SAndroid Build Coastguard Worker if (const PHINode *VP = dyn_cast<PHINode>(I))
635*9880d681SAndroid Build Coastguard Worker if (VP->getParent() == CondPHI->getParent())
636*9880d681SAndroid Build Coastguard Worker return true;
637*9880d681SAndroid Build Coastguard Worker
638*9880d681SAndroid Build Coastguard Worker // Otherwise, if the PHI and select are defined in the same block and if V is
639*9880d681SAndroid Build Coastguard Worker // defined in a different block, then we can transform it.
640*9880d681SAndroid Build Coastguard Worker if (SI.getParent() == CondPHI->getParent() &&
641*9880d681SAndroid Build Coastguard Worker I->getParent() != CondPHI->getParent())
642*9880d681SAndroid Build Coastguard Worker return true;
643*9880d681SAndroid Build Coastguard Worker
644*9880d681SAndroid Build Coastguard Worker // Otherwise we have a 'hard' case and we can't tell without doing more
645*9880d681SAndroid Build Coastguard Worker // detailed dominator based analysis, punt.
646*9880d681SAndroid Build Coastguard Worker return false;
647*9880d681SAndroid Build Coastguard Worker }
648*9880d681SAndroid Build Coastguard Worker
649*9880d681SAndroid Build Coastguard Worker /// We have an SPF (e.g. a min or max) of an SPF of the form:
650*9880d681SAndroid Build Coastguard Worker /// SPF2(SPF1(A, B), C)
FoldSPFofSPF(Instruction * Inner,SelectPatternFlavor SPF1,Value * A,Value * B,Instruction & Outer,SelectPatternFlavor SPF2,Value * C)651*9880d681SAndroid Build Coastguard Worker Instruction *InstCombiner::FoldSPFofSPF(Instruction *Inner,
652*9880d681SAndroid Build Coastguard Worker SelectPatternFlavor SPF1,
653*9880d681SAndroid Build Coastguard Worker Value *A, Value *B,
654*9880d681SAndroid Build Coastguard Worker Instruction &Outer,
655*9880d681SAndroid Build Coastguard Worker SelectPatternFlavor SPF2, Value *C) {
656*9880d681SAndroid Build Coastguard Worker if (Outer.getType() != Inner->getType())
657*9880d681SAndroid Build Coastguard Worker return nullptr;
658*9880d681SAndroid Build Coastguard Worker
659*9880d681SAndroid Build Coastguard Worker if (C == A || C == B) {
660*9880d681SAndroid Build Coastguard Worker // MAX(MAX(A, B), B) -> MAX(A, B)
661*9880d681SAndroid Build Coastguard Worker // MIN(MIN(a, b), a) -> MIN(a, b)
662*9880d681SAndroid Build Coastguard Worker if (SPF1 == SPF2)
663*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(Outer, Inner);
664*9880d681SAndroid Build Coastguard Worker
665*9880d681SAndroid Build Coastguard Worker // MAX(MIN(a, b), a) -> a
666*9880d681SAndroid Build Coastguard Worker // MIN(MAX(a, b), a) -> a
667*9880d681SAndroid Build Coastguard Worker if ((SPF1 == SPF_SMIN && SPF2 == SPF_SMAX) ||
668*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_SMAX && SPF2 == SPF_SMIN) ||
669*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_UMIN && SPF2 == SPF_UMAX) ||
670*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_UMAX && SPF2 == SPF_UMIN))
671*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(Outer, C);
672*9880d681SAndroid Build Coastguard Worker }
673*9880d681SAndroid Build Coastguard Worker
674*9880d681SAndroid Build Coastguard Worker if (SPF1 == SPF2) {
675*9880d681SAndroid Build Coastguard Worker if (ConstantInt *CB = dyn_cast<ConstantInt>(B)) {
676*9880d681SAndroid Build Coastguard Worker if (ConstantInt *CC = dyn_cast<ConstantInt>(C)) {
677*9880d681SAndroid Build Coastguard Worker const APInt &ACB = CB->getValue();
678*9880d681SAndroid Build Coastguard Worker const APInt &ACC = CC->getValue();
679*9880d681SAndroid Build Coastguard Worker
680*9880d681SAndroid Build Coastguard Worker // MIN(MIN(A, 23), 97) -> MIN(A, 23)
681*9880d681SAndroid Build Coastguard Worker // MAX(MAX(A, 97), 23) -> MAX(A, 97)
682*9880d681SAndroid Build Coastguard Worker if ((SPF1 == SPF_UMIN && ACB.ule(ACC)) ||
683*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_SMIN && ACB.sle(ACC)) ||
684*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_UMAX && ACB.uge(ACC)) ||
685*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_SMAX && ACB.sge(ACC)))
686*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(Outer, Inner);
687*9880d681SAndroid Build Coastguard Worker
688*9880d681SAndroid Build Coastguard Worker // MIN(MIN(A, 97), 23) -> MIN(A, 23)
689*9880d681SAndroid Build Coastguard Worker // MAX(MAX(A, 23), 97) -> MAX(A, 97)
690*9880d681SAndroid Build Coastguard Worker if ((SPF1 == SPF_UMIN && ACB.ugt(ACC)) ||
691*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_SMIN && ACB.sgt(ACC)) ||
692*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_UMAX && ACB.ult(ACC)) ||
693*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_SMAX && ACB.slt(ACC))) {
694*9880d681SAndroid Build Coastguard Worker Outer.replaceUsesOfWith(Inner, A);
695*9880d681SAndroid Build Coastguard Worker return &Outer;
696*9880d681SAndroid Build Coastguard Worker }
697*9880d681SAndroid Build Coastguard Worker }
698*9880d681SAndroid Build Coastguard Worker }
699*9880d681SAndroid Build Coastguard Worker }
700*9880d681SAndroid Build Coastguard Worker
701*9880d681SAndroid Build Coastguard Worker // ABS(ABS(X)) -> ABS(X)
702*9880d681SAndroid Build Coastguard Worker // NABS(NABS(X)) -> NABS(X)
703*9880d681SAndroid Build Coastguard Worker if (SPF1 == SPF2 && (SPF1 == SPF_ABS || SPF1 == SPF_NABS)) {
704*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(Outer, Inner);
705*9880d681SAndroid Build Coastguard Worker }
706*9880d681SAndroid Build Coastguard Worker
707*9880d681SAndroid Build Coastguard Worker // ABS(NABS(X)) -> ABS(X)
708*9880d681SAndroid Build Coastguard Worker // NABS(ABS(X)) -> NABS(X)
709*9880d681SAndroid Build Coastguard Worker if ((SPF1 == SPF_ABS && SPF2 == SPF_NABS) ||
710*9880d681SAndroid Build Coastguard Worker (SPF1 == SPF_NABS && SPF2 == SPF_ABS)) {
711*9880d681SAndroid Build Coastguard Worker SelectInst *SI = cast<SelectInst>(Inner);
712*9880d681SAndroid Build Coastguard Worker Value *NewSI = Builder->CreateSelect(
713*9880d681SAndroid Build Coastguard Worker SI->getCondition(), SI->getFalseValue(), SI->getTrueValue());
714*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(Outer, NewSI);
715*9880d681SAndroid Build Coastguard Worker }
716*9880d681SAndroid Build Coastguard Worker
717*9880d681SAndroid Build Coastguard Worker auto IsFreeOrProfitableToInvert =
718*9880d681SAndroid Build Coastguard Worker [&](Value *V, Value *&NotV, bool &ElidesXor) {
719*9880d681SAndroid Build Coastguard Worker if (match(V, m_Not(m_Value(NotV)))) {
720*9880d681SAndroid Build Coastguard Worker // If V has at most 2 uses then we can get rid of the xor operation
721*9880d681SAndroid Build Coastguard Worker // entirely.
722*9880d681SAndroid Build Coastguard Worker ElidesXor |= !V->hasNUsesOrMore(3);
723*9880d681SAndroid Build Coastguard Worker return true;
724*9880d681SAndroid Build Coastguard Worker }
725*9880d681SAndroid Build Coastguard Worker
726*9880d681SAndroid Build Coastguard Worker if (IsFreeToInvert(V, !V->hasNUsesOrMore(3))) {
727*9880d681SAndroid Build Coastguard Worker NotV = nullptr;
728*9880d681SAndroid Build Coastguard Worker return true;
729*9880d681SAndroid Build Coastguard Worker }
730*9880d681SAndroid Build Coastguard Worker
731*9880d681SAndroid Build Coastguard Worker return false;
732*9880d681SAndroid Build Coastguard Worker };
733*9880d681SAndroid Build Coastguard Worker
734*9880d681SAndroid Build Coastguard Worker Value *NotA, *NotB, *NotC;
735*9880d681SAndroid Build Coastguard Worker bool ElidesXor = false;
736*9880d681SAndroid Build Coastguard Worker
737*9880d681SAndroid Build Coastguard Worker // MIN(MIN(~A, ~B), ~C) == ~MAX(MAX(A, B), C)
738*9880d681SAndroid Build Coastguard Worker // MIN(MAX(~A, ~B), ~C) == ~MAX(MIN(A, B), C)
739*9880d681SAndroid Build Coastguard Worker // MAX(MIN(~A, ~B), ~C) == ~MIN(MAX(A, B), C)
740*9880d681SAndroid Build Coastguard Worker // MAX(MAX(~A, ~B), ~C) == ~MIN(MIN(A, B), C)
741*9880d681SAndroid Build Coastguard Worker //
742*9880d681SAndroid Build Coastguard Worker // This transform is performance neutral if we can elide at least one xor from
743*9880d681SAndroid Build Coastguard Worker // the set of three operands, since we'll be tacking on an xor at the very
744*9880d681SAndroid Build Coastguard Worker // end.
745*9880d681SAndroid Build Coastguard Worker if (IsFreeOrProfitableToInvert(A, NotA, ElidesXor) &&
746*9880d681SAndroid Build Coastguard Worker IsFreeOrProfitableToInvert(B, NotB, ElidesXor) &&
747*9880d681SAndroid Build Coastguard Worker IsFreeOrProfitableToInvert(C, NotC, ElidesXor) && ElidesXor) {
748*9880d681SAndroid Build Coastguard Worker if (!NotA)
749*9880d681SAndroid Build Coastguard Worker NotA = Builder->CreateNot(A);
750*9880d681SAndroid Build Coastguard Worker if (!NotB)
751*9880d681SAndroid Build Coastguard Worker NotB = Builder->CreateNot(B);
752*9880d681SAndroid Build Coastguard Worker if (!NotC)
753*9880d681SAndroid Build Coastguard Worker NotC = Builder->CreateNot(C);
754*9880d681SAndroid Build Coastguard Worker
755*9880d681SAndroid Build Coastguard Worker Value *NewInner = generateMinMaxSelectPattern(
756*9880d681SAndroid Build Coastguard Worker Builder, getInverseMinMaxSelectPattern(SPF1), NotA, NotB);
757*9880d681SAndroid Build Coastguard Worker Value *NewOuter = Builder->CreateNot(generateMinMaxSelectPattern(
758*9880d681SAndroid Build Coastguard Worker Builder, getInverseMinMaxSelectPattern(SPF2), NewInner, NotC));
759*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(Outer, NewOuter);
760*9880d681SAndroid Build Coastguard Worker }
761*9880d681SAndroid Build Coastguard Worker
762*9880d681SAndroid Build Coastguard Worker return nullptr;
763*9880d681SAndroid Build Coastguard Worker }
764*9880d681SAndroid Build Coastguard Worker
765*9880d681SAndroid Build Coastguard Worker /// If one of the constants is zero (we know they can't both be) and we have an
766*9880d681SAndroid Build Coastguard Worker /// icmp instruction with zero, and we have an 'and' with the non-constant value
767*9880d681SAndroid Build Coastguard Worker /// and a power of two we can turn the select into a shift on the result of the
768*9880d681SAndroid Build Coastguard Worker /// 'and'.
foldSelectICmpAnd(const SelectInst & SI,ConstantInt * TrueVal,ConstantInt * FalseVal,InstCombiner::BuilderTy * Builder)769*9880d681SAndroid Build Coastguard Worker static Value *foldSelectICmpAnd(const SelectInst &SI, ConstantInt *TrueVal,
770*9880d681SAndroid Build Coastguard Worker ConstantInt *FalseVal,
771*9880d681SAndroid Build Coastguard Worker InstCombiner::BuilderTy *Builder) {
772*9880d681SAndroid Build Coastguard Worker const ICmpInst *IC = dyn_cast<ICmpInst>(SI.getCondition());
773*9880d681SAndroid Build Coastguard Worker if (!IC || !IC->isEquality() || !SI.getType()->isIntegerTy())
774*9880d681SAndroid Build Coastguard Worker return nullptr;
775*9880d681SAndroid Build Coastguard Worker
776*9880d681SAndroid Build Coastguard Worker if (!match(IC->getOperand(1), m_Zero()))
777*9880d681SAndroid Build Coastguard Worker return nullptr;
778*9880d681SAndroid Build Coastguard Worker
779*9880d681SAndroid Build Coastguard Worker ConstantInt *AndRHS;
780*9880d681SAndroid Build Coastguard Worker Value *LHS = IC->getOperand(0);
781*9880d681SAndroid Build Coastguard Worker if (!match(LHS, m_And(m_Value(), m_ConstantInt(AndRHS))))
782*9880d681SAndroid Build Coastguard Worker return nullptr;
783*9880d681SAndroid Build Coastguard Worker
784*9880d681SAndroid Build Coastguard Worker // If both select arms are non-zero see if we have a select of the form
785*9880d681SAndroid Build Coastguard Worker // 'x ? 2^n + C : C'. Then we can offset both arms by C, use the logic
786*9880d681SAndroid Build Coastguard Worker // for 'x ? 2^n : 0' and fix the thing up at the end.
787*9880d681SAndroid Build Coastguard Worker ConstantInt *Offset = nullptr;
788*9880d681SAndroid Build Coastguard Worker if (!TrueVal->isZero() && !FalseVal->isZero()) {
789*9880d681SAndroid Build Coastguard Worker if ((TrueVal->getValue() - FalseVal->getValue()).isPowerOf2())
790*9880d681SAndroid Build Coastguard Worker Offset = FalseVal;
791*9880d681SAndroid Build Coastguard Worker else if ((FalseVal->getValue() - TrueVal->getValue()).isPowerOf2())
792*9880d681SAndroid Build Coastguard Worker Offset = TrueVal;
793*9880d681SAndroid Build Coastguard Worker else
794*9880d681SAndroid Build Coastguard Worker return nullptr;
795*9880d681SAndroid Build Coastguard Worker
796*9880d681SAndroid Build Coastguard Worker // Adjust TrueVal and FalseVal to the offset.
797*9880d681SAndroid Build Coastguard Worker TrueVal = ConstantInt::get(Builder->getContext(),
798*9880d681SAndroid Build Coastguard Worker TrueVal->getValue() - Offset->getValue());
799*9880d681SAndroid Build Coastguard Worker FalseVal = ConstantInt::get(Builder->getContext(),
800*9880d681SAndroid Build Coastguard Worker FalseVal->getValue() - Offset->getValue());
801*9880d681SAndroid Build Coastguard Worker }
802*9880d681SAndroid Build Coastguard Worker
803*9880d681SAndroid Build Coastguard Worker // Make sure the mask in the 'and' and one of the select arms is a power of 2.
804*9880d681SAndroid Build Coastguard Worker if (!AndRHS->getValue().isPowerOf2() ||
805*9880d681SAndroid Build Coastguard Worker (!TrueVal->getValue().isPowerOf2() &&
806*9880d681SAndroid Build Coastguard Worker !FalseVal->getValue().isPowerOf2()))
807*9880d681SAndroid Build Coastguard Worker return nullptr;
808*9880d681SAndroid Build Coastguard Worker
809*9880d681SAndroid Build Coastguard Worker // Determine which shift is needed to transform result of the 'and' into the
810*9880d681SAndroid Build Coastguard Worker // desired result.
811*9880d681SAndroid Build Coastguard Worker ConstantInt *ValC = !TrueVal->isZero() ? TrueVal : FalseVal;
812*9880d681SAndroid Build Coastguard Worker unsigned ValZeros = ValC->getValue().logBase2();
813*9880d681SAndroid Build Coastguard Worker unsigned AndZeros = AndRHS->getValue().logBase2();
814*9880d681SAndroid Build Coastguard Worker
815*9880d681SAndroid Build Coastguard Worker // If types don't match we can still convert the select by introducing a zext
816*9880d681SAndroid Build Coastguard Worker // or a trunc of the 'and'. The trunc case requires that all of the truncated
817*9880d681SAndroid Build Coastguard Worker // bits are zero, we can figure that out by looking at the 'and' mask.
818*9880d681SAndroid Build Coastguard Worker if (AndZeros >= ValC->getBitWidth())
819*9880d681SAndroid Build Coastguard Worker return nullptr;
820*9880d681SAndroid Build Coastguard Worker
821*9880d681SAndroid Build Coastguard Worker Value *V = Builder->CreateZExtOrTrunc(LHS, SI.getType());
822*9880d681SAndroid Build Coastguard Worker if (ValZeros > AndZeros)
823*9880d681SAndroid Build Coastguard Worker V = Builder->CreateShl(V, ValZeros - AndZeros);
824*9880d681SAndroid Build Coastguard Worker else if (ValZeros < AndZeros)
825*9880d681SAndroid Build Coastguard Worker V = Builder->CreateLShr(V, AndZeros - ValZeros);
826*9880d681SAndroid Build Coastguard Worker
827*9880d681SAndroid Build Coastguard Worker // Okay, now we know that everything is set up, we just don't know whether we
828*9880d681SAndroid Build Coastguard Worker // have a icmp_ne or icmp_eq and whether the true or false val is the zero.
829*9880d681SAndroid Build Coastguard Worker bool ShouldNotVal = !TrueVal->isZero();
830*9880d681SAndroid Build Coastguard Worker ShouldNotVal ^= IC->getPredicate() == ICmpInst::ICMP_NE;
831*9880d681SAndroid Build Coastguard Worker if (ShouldNotVal)
832*9880d681SAndroid Build Coastguard Worker V = Builder->CreateXor(V, ValC);
833*9880d681SAndroid Build Coastguard Worker
834*9880d681SAndroid Build Coastguard Worker // Apply an offset if needed.
835*9880d681SAndroid Build Coastguard Worker if (Offset)
836*9880d681SAndroid Build Coastguard Worker V = Builder->CreateAdd(V, Offset);
837*9880d681SAndroid Build Coastguard Worker return V;
838*9880d681SAndroid Build Coastguard Worker }
839*9880d681SAndroid Build Coastguard Worker
840*9880d681SAndroid Build Coastguard Worker /// Turn select C, (X + Y), (X - Y) --> (X + (select C, Y, (-Y))).
841*9880d681SAndroid Build Coastguard Worker /// This is even legal for FP.
foldAddSubSelect(SelectInst & SI,InstCombiner::BuilderTy & Builder)842*9880d681SAndroid Build Coastguard Worker static Instruction *foldAddSubSelect(SelectInst &SI,
843*9880d681SAndroid Build Coastguard Worker InstCombiner::BuilderTy &Builder) {
844*9880d681SAndroid Build Coastguard Worker Value *CondVal = SI.getCondition();
845*9880d681SAndroid Build Coastguard Worker Value *TrueVal = SI.getTrueValue();
846*9880d681SAndroid Build Coastguard Worker Value *FalseVal = SI.getFalseValue();
847*9880d681SAndroid Build Coastguard Worker auto *TI = dyn_cast<Instruction>(TrueVal);
848*9880d681SAndroid Build Coastguard Worker auto *FI = dyn_cast<Instruction>(FalseVal);
849*9880d681SAndroid Build Coastguard Worker if (!TI || !FI || !TI->hasOneUse() || !FI->hasOneUse())
850*9880d681SAndroid Build Coastguard Worker return nullptr;
851*9880d681SAndroid Build Coastguard Worker
852*9880d681SAndroid Build Coastguard Worker Instruction *AddOp = nullptr, *SubOp = nullptr;
853*9880d681SAndroid Build Coastguard Worker if ((TI->getOpcode() == Instruction::Sub &&
854*9880d681SAndroid Build Coastguard Worker FI->getOpcode() == Instruction::Add) ||
855*9880d681SAndroid Build Coastguard Worker (TI->getOpcode() == Instruction::FSub &&
856*9880d681SAndroid Build Coastguard Worker FI->getOpcode() == Instruction::FAdd)) {
857*9880d681SAndroid Build Coastguard Worker AddOp = FI;
858*9880d681SAndroid Build Coastguard Worker SubOp = TI;
859*9880d681SAndroid Build Coastguard Worker } else if ((FI->getOpcode() == Instruction::Sub &&
860*9880d681SAndroid Build Coastguard Worker TI->getOpcode() == Instruction::Add) ||
861*9880d681SAndroid Build Coastguard Worker (FI->getOpcode() == Instruction::FSub &&
862*9880d681SAndroid Build Coastguard Worker TI->getOpcode() == Instruction::FAdd)) {
863*9880d681SAndroid Build Coastguard Worker AddOp = TI;
864*9880d681SAndroid Build Coastguard Worker SubOp = FI;
865*9880d681SAndroid Build Coastguard Worker }
866*9880d681SAndroid Build Coastguard Worker
867*9880d681SAndroid Build Coastguard Worker if (AddOp) {
868*9880d681SAndroid Build Coastguard Worker Value *OtherAddOp = nullptr;
869*9880d681SAndroid Build Coastguard Worker if (SubOp->getOperand(0) == AddOp->getOperand(0)) {
870*9880d681SAndroid Build Coastguard Worker OtherAddOp = AddOp->getOperand(1);
871*9880d681SAndroid Build Coastguard Worker } else if (SubOp->getOperand(0) == AddOp->getOperand(1)) {
872*9880d681SAndroid Build Coastguard Worker OtherAddOp = AddOp->getOperand(0);
873*9880d681SAndroid Build Coastguard Worker }
874*9880d681SAndroid Build Coastguard Worker
875*9880d681SAndroid Build Coastguard Worker if (OtherAddOp) {
876*9880d681SAndroid Build Coastguard Worker // So at this point we know we have (Y -> OtherAddOp):
877*9880d681SAndroid Build Coastguard Worker // select C, (add X, Y), (sub X, Z)
878*9880d681SAndroid Build Coastguard Worker Value *NegVal; // Compute -Z
879*9880d681SAndroid Build Coastguard Worker if (SI.getType()->isFPOrFPVectorTy()) {
880*9880d681SAndroid Build Coastguard Worker NegVal = Builder.CreateFNeg(SubOp->getOperand(1));
881*9880d681SAndroid Build Coastguard Worker if (Instruction *NegInst = dyn_cast<Instruction>(NegVal)) {
882*9880d681SAndroid Build Coastguard Worker FastMathFlags Flags = AddOp->getFastMathFlags();
883*9880d681SAndroid Build Coastguard Worker Flags &= SubOp->getFastMathFlags();
884*9880d681SAndroid Build Coastguard Worker NegInst->setFastMathFlags(Flags);
885*9880d681SAndroid Build Coastguard Worker }
886*9880d681SAndroid Build Coastguard Worker } else {
887*9880d681SAndroid Build Coastguard Worker NegVal = Builder.CreateNeg(SubOp->getOperand(1));
888*9880d681SAndroid Build Coastguard Worker }
889*9880d681SAndroid Build Coastguard Worker
890*9880d681SAndroid Build Coastguard Worker Value *NewTrueOp = OtherAddOp;
891*9880d681SAndroid Build Coastguard Worker Value *NewFalseOp = NegVal;
892*9880d681SAndroid Build Coastguard Worker if (AddOp != TI)
893*9880d681SAndroid Build Coastguard Worker std::swap(NewTrueOp, NewFalseOp);
894*9880d681SAndroid Build Coastguard Worker Value *NewSel = Builder.CreateSelect(CondVal, NewTrueOp, NewFalseOp,
895*9880d681SAndroid Build Coastguard Worker SI.getName() + ".p");
896*9880d681SAndroid Build Coastguard Worker
897*9880d681SAndroid Build Coastguard Worker if (SI.getType()->isFPOrFPVectorTy()) {
898*9880d681SAndroid Build Coastguard Worker Instruction *RI =
899*9880d681SAndroid Build Coastguard Worker BinaryOperator::CreateFAdd(SubOp->getOperand(0), NewSel);
900*9880d681SAndroid Build Coastguard Worker
901*9880d681SAndroid Build Coastguard Worker FastMathFlags Flags = AddOp->getFastMathFlags();
902*9880d681SAndroid Build Coastguard Worker Flags &= SubOp->getFastMathFlags();
903*9880d681SAndroid Build Coastguard Worker RI->setFastMathFlags(Flags);
904*9880d681SAndroid Build Coastguard Worker return RI;
905*9880d681SAndroid Build Coastguard Worker } else
906*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateAdd(SubOp->getOperand(0), NewSel);
907*9880d681SAndroid Build Coastguard Worker }
908*9880d681SAndroid Build Coastguard Worker }
909*9880d681SAndroid Build Coastguard Worker return nullptr;
910*9880d681SAndroid Build Coastguard Worker }
911*9880d681SAndroid Build Coastguard Worker
visitSelectInst(SelectInst & SI)912*9880d681SAndroid Build Coastguard Worker Instruction *InstCombiner::visitSelectInst(SelectInst &SI) {
913*9880d681SAndroid Build Coastguard Worker Value *CondVal = SI.getCondition();
914*9880d681SAndroid Build Coastguard Worker Value *TrueVal = SI.getTrueValue();
915*9880d681SAndroid Build Coastguard Worker Value *FalseVal = SI.getFalseValue();
916*9880d681SAndroid Build Coastguard Worker Type *SelType = SI.getType();
917*9880d681SAndroid Build Coastguard Worker
918*9880d681SAndroid Build Coastguard Worker if (Value *V =
919*9880d681SAndroid Build Coastguard Worker SimplifySelectInst(CondVal, TrueVal, FalseVal, DL, TLI, DT, AC))
920*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
921*9880d681SAndroid Build Coastguard Worker
922*9880d681SAndroid Build Coastguard Worker if (SelType->getScalarType()->isIntegerTy(1) &&
923*9880d681SAndroid Build Coastguard Worker TrueVal->getType() == CondVal->getType()) {
924*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_One())) {
925*9880d681SAndroid Build Coastguard Worker // Change: A = select B, true, C --> A = or B, C
926*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateOr(CondVal, FalseVal);
927*9880d681SAndroid Build Coastguard Worker }
928*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_Zero())) {
929*9880d681SAndroid Build Coastguard Worker // Change: A = select B, false, C --> A = and !B, C
930*9880d681SAndroid Build Coastguard Worker Value *NotCond = Builder->CreateNot(CondVal, "not." + CondVal->getName());
931*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateAnd(NotCond, FalseVal);
932*9880d681SAndroid Build Coastguard Worker }
933*9880d681SAndroid Build Coastguard Worker if (match(FalseVal, m_Zero())) {
934*9880d681SAndroid Build Coastguard Worker // Change: A = select B, C, false --> A = and B, C
935*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateAnd(CondVal, TrueVal);
936*9880d681SAndroid Build Coastguard Worker }
937*9880d681SAndroid Build Coastguard Worker if (match(FalseVal, m_One())) {
938*9880d681SAndroid Build Coastguard Worker // Change: A = select B, C, true --> A = or !B, C
939*9880d681SAndroid Build Coastguard Worker Value *NotCond = Builder->CreateNot(CondVal, "not." + CondVal->getName());
940*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateOr(NotCond, TrueVal);
941*9880d681SAndroid Build Coastguard Worker }
942*9880d681SAndroid Build Coastguard Worker
943*9880d681SAndroid Build Coastguard Worker // select a, a, b -> a | b
944*9880d681SAndroid Build Coastguard Worker // select a, b, a -> a & b
945*9880d681SAndroid Build Coastguard Worker if (CondVal == TrueVal)
946*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateOr(CondVal, FalseVal);
947*9880d681SAndroid Build Coastguard Worker if (CondVal == FalseVal)
948*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateAnd(CondVal, TrueVal);
949*9880d681SAndroid Build Coastguard Worker
950*9880d681SAndroid Build Coastguard Worker // select a, ~a, b -> (~a) & b
951*9880d681SAndroid Build Coastguard Worker // select a, b, ~a -> (~a) | b
952*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_Not(m_Specific(CondVal))))
953*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateAnd(TrueVal, FalseVal);
954*9880d681SAndroid Build Coastguard Worker if (match(FalseVal, m_Not(m_Specific(CondVal))))
955*9880d681SAndroid Build Coastguard Worker return BinaryOperator::CreateOr(TrueVal, FalseVal);
956*9880d681SAndroid Build Coastguard Worker }
957*9880d681SAndroid Build Coastguard Worker
958*9880d681SAndroid Build Coastguard Worker // Selecting between two integer or vector splat integer constants?
959*9880d681SAndroid Build Coastguard Worker //
960*9880d681SAndroid Build Coastguard Worker // Note that we don't handle a scalar select of vectors:
961*9880d681SAndroid Build Coastguard Worker // select i1 %c, <2 x i8> <1, 1>, <2 x i8> <0, 0>
962*9880d681SAndroid Build Coastguard Worker // because that may need 3 instructions to splat the condition value:
963*9880d681SAndroid Build Coastguard Worker // extend, insertelement, shufflevector.
964*9880d681SAndroid Build Coastguard Worker if (CondVal->getType()->isVectorTy() == SelType->isVectorTy()) {
965*9880d681SAndroid Build Coastguard Worker // select C, 1, 0 -> zext C to int
966*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_One()) && match(FalseVal, m_Zero()))
967*9880d681SAndroid Build Coastguard Worker return new ZExtInst(CondVal, SelType);
968*9880d681SAndroid Build Coastguard Worker
969*9880d681SAndroid Build Coastguard Worker // select C, -1, 0 -> sext C to int
970*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_AllOnes()) && match(FalseVal, m_Zero()))
971*9880d681SAndroid Build Coastguard Worker return new SExtInst(CondVal, SelType);
972*9880d681SAndroid Build Coastguard Worker
973*9880d681SAndroid Build Coastguard Worker // select C, 0, 1 -> zext !C to int
974*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_Zero()) && match(FalseVal, m_One())) {
975*9880d681SAndroid Build Coastguard Worker Value *NotCond = Builder->CreateNot(CondVal, "not." + CondVal->getName());
976*9880d681SAndroid Build Coastguard Worker return new ZExtInst(NotCond, SelType);
977*9880d681SAndroid Build Coastguard Worker }
978*9880d681SAndroid Build Coastguard Worker
979*9880d681SAndroid Build Coastguard Worker // select C, 0, -1 -> sext !C to int
980*9880d681SAndroid Build Coastguard Worker if (match(TrueVal, m_Zero()) && match(FalseVal, m_AllOnes())) {
981*9880d681SAndroid Build Coastguard Worker Value *NotCond = Builder->CreateNot(CondVal, "not." + CondVal->getName());
982*9880d681SAndroid Build Coastguard Worker return new SExtInst(NotCond, SelType);
983*9880d681SAndroid Build Coastguard Worker }
984*9880d681SAndroid Build Coastguard Worker }
985*9880d681SAndroid Build Coastguard Worker
986*9880d681SAndroid Build Coastguard Worker if (ConstantInt *TrueValC = dyn_cast<ConstantInt>(TrueVal))
987*9880d681SAndroid Build Coastguard Worker if (ConstantInt *FalseValC = dyn_cast<ConstantInt>(FalseVal))
988*9880d681SAndroid Build Coastguard Worker if (Value *V = foldSelectICmpAnd(SI, TrueValC, FalseValC, Builder))
989*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
990*9880d681SAndroid Build Coastguard Worker
991*9880d681SAndroid Build Coastguard Worker // See if we are selecting two values based on a comparison of the two values.
992*9880d681SAndroid Build Coastguard Worker if (FCmpInst *FCI = dyn_cast<FCmpInst>(CondVal)) {
993*9880d681SAndroid Build Coastguard Worker if (FCI->getOperand(0) == TrueVal && FCI->getOperand(1) == FalseVal) {
994*9880d681SAndroid Build Coastguard Worker // Transform (X == Y) ? X : Y -> Y
995*9880d681SAndroid Build Coastguard Worker if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) {
996*9880d681SAndroid Build Coastguard Worker // This is not safe in general for floating point:
997*9880d681SAndroid Build Coastguard Worker // consider X== -0, Y== +0.
998*9880d681SAndroid Build Coastguard Worker // It becomes safe if either operand is a nonzero constant.
999*9880d681SAndroid Build Coastguard Worker ConstantFP *CFPt, *CFPf;
1000*9880d681SAndroid Build Coastguard Worker if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
1001*9880d681SAndroid Build Coastguard Worker !CFPt->getValueAPF().isZero()) ||
1002*9880d681SAndroid Build Coastguard Worker ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
1003*9880d681SAndroid Build Coastguard Worker !CFPf->getValueAPF().isZero()))
1004*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, FalseVal);
1005*9880d681SAndroid Build Coastguard Worker }
1006*9880d681SAndroid Build Coastguard Worker // Transform (X une Y) ? X : Y -> X
1007*9880d681SAndroid Build Coastguard Worker if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
1008*9880d681SAndroid Build Coastguard Worker // This is not safe in general for floating point:
1009*9880d681SAndroid Build Coastguard Worker // consider X== -0, Y== +0.
1010*9880d681SAndroid Build Coastguard Worker // It becomes safe if either operand is a nonzero constant.
1011*9880d681SAndroid Build Coastguard Worker ConstantFP *CFPt, *CFPf;
1012*9880d681SAndroid Build Coastguard Worker if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
1013*9880d681SAndroid Build Coastguard Worker !CFPt->getValueAPF().isZero()) ||
1014*9880d681SAndroid Build Coastguard Worker ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
1015*9880d681SAndroid Build Coastguard Worker !CFPf->getValueAPF().isZero()))
1016*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, TrueVal);
1017*9880d681SAndroid Build Coastguard Worker }
1018*9880d681SAndroid Build Coastguard Worker
1019*9880d681SAndroid Build Coastguard Worker // Canonicalize to use ordered comparisons by swapping the select
1020*9880d681SAndroid Build Coastguard Worker // operands.
1021*9880d681SAndroid Build Coastguard Worker //
1022*9880d681SAndroid Build Coastguard Worker // e.g.
1023*9880d681SAndroid Build Coastguard Worker // (X ugt Y) ? X : Y -> (X ole Y) ? Y : X
1024*9880d681SAndroid Build Coastguard Worker if (FCI->hasOneUse() && FCmpInst::isUnordered(FCI->getPredicate())) {
1025*9880d681SAndroid Build Coastguard Worker FCmpInst::Predicate InvPred = FCI->getInversePredicate();
1026*9880d681SAndroid Build Coastguard Worker IRBuilder<>::FastMathFlagGuard FMFG(*Builder);
1027*9880d681SAndroid Build Coastguard Worker Builder->setFastMathFlags(FCI->getFastMathFlags());
1028*9880d681SAndroid Build Coastguard Worker Value *NewCond = Builder->CreateFCmp(InvPred, TrueVal, FalseVal,
1029*9880d681SAndroid Build Coastguard Worker FCI->getName() + ".inv");
1030*9880d681SAndroid Build Coastguard Worker
1031*9880d681SAndroid Build Coastguard Worker return SelectInst::Create(NewCond, FalseVal, TrueVal,
1032*9880d681SAndroid Build Coastguard Worker SI.getName() + ".p");
1033*9880d681SAndroid Build Coastguard Worker }
1034*9880d681SAndroid Build Coastguard Worker
1035*9880d681SAndroid Build Coastguard Worker // NOTE: if we wanted to, this is where to detect MIN/MAX
1036*9880d681SAndroid Build Coastguard Worker } else if (FCI->getOperand(0) == FalseVal && FCI->getOperand(1) == TrueVal){
1037*9880d681SAndroid Build Coastguard Worker // Transform (X == Y) ? Y : X -> X
1038*9880d681SAndroid Build Coastguard Worker if (FCI->getPredicate() == FCmpInst::FCMP_OEQ) {
1039*9880d681SAndroid Build Coastguard Worker // This is not safe in general for floating point:
1040*9880d681SAndroid Build Coastguard Worker // consider X== -0, Y== +0.
1041*9880d681SAndroid Build Coastguard Worker // It becomes safe if either operand is a nonzero constant.
1042*9880d681SAndroid Build Coastguard Worker ConstantFP *CFPt, *CFPf;
1043*9880d681SAndroid Build Coastguard Worker if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
1044*9880d681SAndroid Build Coastguard Worker !CFPt->getValueAPF().isZero()) ||
1045*9880d681SAndroid Build Coastguard Worker ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
1046*9880d681SAndroid Build Coastguard Worker !CFPf->getValueAPF().isZero()))
1047*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, FalseVal);
1048*9880d681SAndroid Build Coastguard Worker }
1049*9880d681SAndroid Build Coastguard Worker // Transform (X une Y) ? Y : X -> Y
1050*9880d681SAndroid Build Coastguard Worker if (FCI->getPredicate() == FCmpInst::FCMP_UNE) {
1051*9880d681SAndroid Build Coastguard Worker // This is not safe in general for floating point:
1052*9880d681SAndroid Build Coastguard Worker // consider X== -0, Y== +0.
1053*9880d681SAndroid Build Coastguard Worker // It becomes safe if either operand is a nonzero constant.
1054*9880d681SAndroid Build Coastguard Worker ConstantFP *CFPt, *CFPf;
1055*9880d681SAndroid Build Coastguard Worker if (((CFPt = dyn_cast<ConstantFP>(TrueVal)) &&
1056*9880d681SAndroid Build Coastguard Worker !CFPt->getValueAPF().isZero()) ||
1057*9880d681SAndroid Build Coastguard Worker ((CFPf = dyn_cast<ConstantFP>(FalseVal)) &&
1058*9880d681SAndroid Build Coastguard Worker !CFPf->getValueAPF().isZero()))
1059*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, TrueVal);
1060*9880d681SAndroid Build Coastguard Worker }
1061*9880d681SAndroid Build Coastguard Worker
1062*9880d681SAndroid Build Coastguard Worker // Canonicalize to use ordered comparisons by swapping the select
1063*9880d681SAndroid Build Coastguard Worker // operands.
1064*9880d681SAndroid Build Coastguard Worker //
1065*9880d681SAndroid Build Coastguard Worker // e.g.
1066*9880d681SAndroid Build Coastguard Worker // (X ugt Y) ? X : Y -> (X ole Y) ? X : Y
1067*9880d681SAndroid Build Coastguard Worker if (FCI->hasOneUse() && FCmpInst::isUnordered(FCI->getPredicate())) {
1068*9880d681SAndroid Build Coastguard Worker FCmpInst::Predicate InvPred = FCI->getInversePredicate();
1069*9880d681SAndroid Build Coastguard Worker IRBuilder<>::FastMathFlagGuard FMFG(*Builder);
1070*9880d681SAndroid Build Coastguard Worker Builder->setFastMathFlags(FCI->getFastMathFlags());
1071*9880d681SAndroid Build Coastguard Worker Value *NewCond = Builder->CreateFCmp(InvPred, FalseVal, TrueVal,
1072*9880d681SAndroid Build Coastguard Worker FCI->getName() + ".inv");
1073*9880d681SAndroid Build Coastguard Worker
1074*9880d681SAndroid Build Coastguard Worker return SelectInst::Create(NewCond, FalseVal, TrueVal,
1075*9880d681SAndroid Build Coastguard Worker SI.getName() + ".p");
1076*9880d681SAndroid Build Coastguard Worker }
1077*9880d681SAndroid Build Coastguard Worker
1078*9880d681SAndroid Build Coastguard Worker // NOTE: if we wanted to, this is where to detect MIN/MAX
1079*9880d681SAndroid Build Coastguard Worker }
1080*9880d681SAndroid Build Coastguard Worker // NOTE: if we wanted to, this is where to detect ABS
1081*9880d681SAndroid Build Coastguard Worker }
1082*9880d681SAndroid Build Coastguard Worker
1083*9880d681SAndroid Build Coastguard Worker // See if we are selecting two values based on a comparison of the two values.
1084*9880d681SAndroid Build Coastguard Worker if (ICmpInst *ICI = dyn_cast<ICmpInst>(CondVal))
1085*9880d681SAndroid Build Coastguard Worker if (Instruction *Result = visitSelectInstWithICmp(SI, ICI))
1086*9880d681SAndroid Build Coastguard Worker return Result;
1087*9880d681SAndroid Build Coastguard Worker
1088*9880d681SAndroid Build Coastguard Worker if (Instruction *Add = foldAddSubSelect(SI, *Builder))
1089*9880d681SAndroid Build Coastguard Worker return Add;
1090*9880d681SAndroid Build Coastguard Worker
1091*9880d681SAndroid Build Coastguard Worker // Turn (select C, (op X, Y), (op X, Z)) -> (op X, (select C, Y, Z))
1092*9880d681SAndroid Build Coastguard Worker auto *TI = dyn_cast<Instruction>(TrueVal);
1093*9880d681SAndroid Build Coastguard Worker auto *FI = dyn_cast<Instruction>(FalseVal);
1094*9880d681SAndroid Build Coastguard Worker if (TI && FI && TI->getOpcode() == FI->getOpcode())
1095*9880d681SAndroid Build Coastguard Worker if (Instruction *IV = FoldSelectOpOp(SI, TI, FI))
1096*9880d681SAndroid Build Coastguard Worker return IV;
1097*9880d681SAndroid Build Coastguard Worker
1098*9880d681SAndroid Build Coastguard Worker // See if we can fold the select into one of our operands.
1099*9880d681SAndroid Build Coastguard Worker if (SelType->isIntOrIntVectorTy() || SelType->isFPOrFPVectorTy()) {
1100*9880d681SAndroid Build Coastguard Worker if (Instruction *FoldI = FoldSelectIntoOp(SI, TrueVal, FalseVal))
1101*9880d681SAndroid Build Coastguard Worker return FoldI;
1102*9880d681SAndroid Build Coastguard Worker
1103*9880d681SAndroid Build Coastguard Worker Value *LHS, *RHS, *LHS2, *RHS2;
1104*9880d681SAndroid Build Coastguard Worker Instruction::CastOps CastOp;
1105*9880d681SAndroid Build Coastguard Worker SelectPatternResult SPR = matchSelectPattern(&SI, LHS, RHS, &CastOp);
1106*9880d681SAndroid Build Coastguard Worker auto SPF = SPR.Flavor;
1107*9880d681SAndroid Build Coastguard Worker
1108*9880d681SAndroid Build Coastguard Worker if (SelectPatternResult::isMinOrMax(SPF)) {
1109*9880d681SAndroid Build Coastguard Worker // Canonicalize so that type casts are outside select patterns.
1110*9880d681SAndroid Build Coastguard Worker if (LHS->getType()->getPrimitiveSizeInBits() !=
1111*9880d681SAndroid Build Coastguard Worker SelType->getPrimitiveSizeInBits()) {
1112*9880d681SAndroid Build Coastguard Worker CmpInst::Predicate Pred = getCmpPredicateForMinMax(SPF, SPR.Ordered);
1113*9880d681SAndroid Build Coastguard Worker
1114*9880d681SAndroid Build Coastguard Worker Value *Cmp;
1115*9880d681SAndroid Build Coastguard Worker if (CmpInst::isIntPredicate(Pred)) {
1116*9880d681SAndroid Build Coastguard Worker Cmp = Builder->CreateICmp(Pred, LHS, RHS);
1117*9880d681SAndroid Build Coastguard Worker } else {
1118*9880d681SAndroid Build Coastguard Worker IRBuilder<>::FastMathFlagGuard FMFG(*Builder);
1119*9880d681SAndroid Build Coastguard Worker auto FMF = cast<FPMathOperator>(SI.getCondition())->getFastMathFlags();
1120*9880d681SAndroid Build Coastguard Worker Builder->setFastMathFlags(FMF);
1121*9880d681SAndroid Build Coastguard Worker Cmp = Builder->CreateFCmp(Pred, LHS, RHS);
1122*9880d681SAndroid Build Coastguard Worker }
1123*9880d681SAndroid Build Coastguard Worker
1124*9880d681SAndroid Build Coastguard Worker Value *NewSI = Builder->CreateCast(CastOp,
1125*9880d681SAndroid Build Coastguard Worker Builder->CreateSelect(Cmp, LHS, RHS),
1126*9880d681SAndroid Build Coastguard Worker SelType);
1127*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, NewSI);
1128*9880d681SAndroid Build Coastguard Worker }
1129*9880d681SAndroid Build Coastguard Worker }
1130*9880d681SAndroid Build Coastguard Worker
1131*9880d681SAndroid Build Coastguard Worker if (SPF) {
1132*9880d681SAndroid Build Coastguard Worker // MAX(MAX(a, b), a) -> MAX(a, b)
1133*9880d681SAndroid Build Coastguard Worker // MIN(MIN(a, b), a) -> MIN(a, b)
1134*9880d681SAndroid Build Coastguard Worker // MAX(MIN(a, b), a) -> a
1135*9880d681SAndroid Build Coastguard Worker // MIN(MAX(a, b), a) -> a
1136*9880d681SAndroid Build Coastguard Worker // ABS(ABS(a)) -> ABS(a)
1137*9880d681SAndroid Build Coastguard Worker // NABS(NABS(a)) -> NABS(a)
1138*9880d681SAndroid Build Coastguard Worker if (SelectPatternFlavor SPF2 = matchSelectPattern(LHS, LHS2, RHS2).Flavor)
1139*9880d681SAndroid Build Coastguard Worker if (Instruction *R = FoldSPFofSPF(cast<Instruction>(LHS),SPF2,LHS2,RHS2,
1140*9880d681SAndroid Build Coastguard Worker SI, SPF, RHS))
1141*9880d681SAndroid Build Coastguard Worker return R;
1142*9880d681SAndroid Build Coastguard Worker if (SelectPatternFlavor SPF2 = matchSelectPattern(RHS, LHS2, RHS2).Flavor)
1143*9880d681SAndroid Build Coastguard Worker if (Instruction *R = FoldSPFofSPF(cast<Instruction>(RHS),SPF2,LHS2,RHS2,
1144*9880d681SAndroid Build Coastguard Worker SI, SPF, LHS))
1145*9880d681SAndroid Build Coastguard Worker return R;
1146*9880d681SAndroid Build Coastguard Worker }
1147*9880d681SAndroid Build Coastguard Worker
1148*9880d681SAndroid Build Coastguard Worker // MAX(~a, ~b) -> ~MIN(a, b)
1149*9880d681SAndroid Build Coastguard Worker if (SPF == SPF_SMAX || SPF == SPF_UMAX) {
1150*9880d681SAndroid Build Coastguard Worker if (IsFreeToInvert(LHS, LHS->hasNUses(2)) &&
1151*9880d681SAndroid Build Coastguard Worker IsFreeToInvert(RHS, RHS->hasNUses(2))) {
1152*9880d681SAndroid Build Coastguard Worker
1153*9880d681SAndroid Build Coastguard Worker // This transform adds a xor operation and that extra cost needs to be
1154*9880d681SAndroid Build Coastguard Worker // justified. We look for simplifications that will result from
1155*9880d681SAndroid Build Coastguard Worker // applying this rule:
1156*9880d681SAndroid Build Coastguard Worker
1157*9880d681SAndroid Build Coastguard Worker bool Profitable =
1158*9880d681SAndroid Build Coastguard Worker (LHS->hasNUses(2) && match(LHS, m_Not(m_Value()))) ||
1159*9880d681SAndroid Build Coastguard Worker (RHS->hasNUses(2) && match(RHS, m_Not(m_Value()))) ||
1160*9880d681SAndroid Build Coastguard Worker (SI.hasOneUse() && match(*SI.user_begin(), m_Not(m_Value())));
1161*9880d681SAndroid Build Coastguard Worker
1162*9880d681SAndroid Build Coastguard Worker if (Profitable) {
1163*9880d681SAndroid Build Coastguard Worker Value *NewLHS = Builder->CreateNot(LHS);
1164*9880d681SAndroid Build Coastguard Worker Value *NewRHS = Builder->CreateNot(RHS);
1165*9880d681SAndroid Build Coastguard Worker Value *NewCmp = SPF == SPF_SMAX
1166*9880d681SAndroid Build Coastguard Worker ? Builder->CreateICmpSLT(NewLHS, NewRHS)
1167*9880d681SAndroid Build Coastguard Worker : Builder->CreateICmpULT(NewLHS, NewRHS);
1168*9880d681SAndroid Build Coastguard Worker Value *NewSI =
1169*9880d681SAndroid Build Coastguard Worker Builder->CreateNot(Builder->CreateSelect(NewCmp, NewLHS, NewRHS));
1170*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, NewSI);
1171*9880d681SAndroid Build Coastguard Worker }
1172*9880d681SAndroid Build Coastguard Worker }
1173*9880d681SAndroid Build Coastguard Worker }
1174*9880d681SAndroid Build Coastguard Worker
1175*9880d681SAndroid Build Coastguard Worker // TODO.
1176*9880d681SAndroid Build Coastguard Worker // ABS(-X) -> ABS(X)
1177*9880d681SAndroid Build Coastguard Worker }
1178*9880d681SAndroid Build Coastguard Worker
1179*9880d681SAndroid Build Coastguard Worker // See if we can fold the select into a phi node if the condition is a select.
1180*9880d681SAndroid Build Coastguard Worker if (isa<PHINode>(SI.getCondition()))
1181*9880d681SAndroid Build Coastguard Worker // The true/false values have to be live in the PHI predecessor's blocks.
1182*9880d681SAndroid Build Coastguard Worker if (CanSelectOperandBeMappingIntoPredBlock(TrueVal, SI) &&
1183*9880d681SAndroid Build Coastguard Worker CanSelectOperandBeMappingIntoPredBlock(FalseVal, SI))
1184*9880d681SAndroid Build Coastguard Worker if (Instruction *NV = FoldOpIntoPhi(SI))
1185*9880d681SAndroid Build Coastguard Worker return NV;
1186*9880d681SAndroid Build Coastguard Worker
1187*9880d681SAndroid Build Coastguard Worker if (SelectInst *TrueSI = dyn_cast<SelectInst>(TrueVal)) {
1188*9880d681SAndroid Build Coastguard Worker if (TrueSI->getCondition()->getType() == CondVal->getType()) {
1189*9880d681SAndroid Build Coastguard Worker // select(C, select(C, a, b), c) -> select(C, a, c)
1190*9880d681SAndroid Build Coastguard Worker if (TrueSI->getCondition() == CondVal) {
1191*9880d681SAndroid Build Coastguard Worker if (SI.getTrueValue() == TrueSI->getTrueValue())
1192*9880d681SAndroid Build Coastguard Worker return nullptr;
1193*9880d681SAndroid Build Coastguard Worker SI.setOperand(1, TrueSI->getTrueValue());
1194*9880d681SAndroid Build Coastguard Worker return &SI;
1195*9880d681SAndroid Build Coastguard Worker }
1196*9880d681SAndroid Build Coastguard Worker // select(C0, select(C1, a, b), b) -> select(C0&C1, a, b)
1197*9880d681SAndroid Build Coastguard Worker // We choose this as normal form to enable folding on the And and shortening
1198*9880d681SAndroid Build Coastguard Worker // paths for the values (this helps GetUnderlyingObjects() for example).
1199*9880d681SAndroid Build Coastguard Worker if (TrueSI->getFalseValue() == FalseVal && TrueSI->hasOneUse()) {
1200*9880d681SAndroid Build Coastguard Worker Value *And = Builder->CreateAnd(CondVal, TrueSI->getCondition());
1201*9880d681SAndroid Build Coastguard Worker SI.setOperand(0, And);
1202*9880d681SAndroid Build Coastguard Worker SI.setOperand(1, TrueSI->getTrueValue());
1203*9880d681SAndroid Build Coastguard Worker return &SI;
1204*9880d681SAndroid Build Coastguard Worker }
1205*9880d681SAndroid Build Coastguard Worker }
1206*9880d681SAndroid Build Coastguard Worker }
1207*9880d681SAndroid Build Coastguard Worker if (SelectInst *FalseSI = dyn_cast<SelectInst>(FalseVal)) {
1208*9880d681SAndroid Build Coastguard Worker if (FalseSI->getCondition()->getType() == CondVal->getType()) {
1209*9880d681SAndroid Build Coastguard Worker // select(C, a, select(C, b, c)) -> select(C, a, c)
1210*9880d681SAndroid Build Coastguard Worker if (FalseSI->getCondition() == CondVal) {
1211*9880d681SAndroid Build Coastguard Worker if (SI.getFalseValue() == FalseSI->getFalseValue())
1212*9880d681SAndroid Build Coastguard Worker return nullptr;
1213*9880d681SAndroid Build Coastguard Worker SI.setOperand(2, FalseSI->getFalseValue());
1214*9880d681SAndroid Build Coastguard Worker return &SI;
1215*9880d681SAndroid Build Coastguard Worker }
1216*9880d681SAndroid Build Coastguard Worker // select(C0, a, select(C1, a, b)) -> select(C0|C1, a, b)
1217*9880d681SAndroid Build Coastguard Worker if (FalseSI->getTrueValue() == TrueVal && FalseSI->hasOneUse()) {
1218*9880d681SAndroid Build Coastguard Worker Value *Or = Builder->CreateOr(CondVal, FalseSI->getCondition());
1219*9880d681SAndroid Build Coastguard Worker SI.setOperand(0, Or);
1220*9880d681SAndroid Build Coastguard Worker SI.setOperand(2, FalseSI->getFalseValue());
1221*9880d681SAndroid Build Coastguard Worker return &SI;
1222*9880d681SAndroid Build Coastguard Worker }
1223*9880d681SAndroid Build Coastguard Worker }
1224*9880d681SAndroid Build Coastguard Worker }
1225*9880d681SAndroid Build Coastguard Worker
1226*9880d681SAndroid Build Coastguard Worker if (BinaryOperator::isNot(CondVal)) {
1227*9880d681SAndroid Build Coastguard Worker SI.setOperand(0, BinaryOperator::getNotArgument(CondVal));
1228*9880d681SAndroid Build Coastguard Worker SI.setOperand(1, FalseVal);
1229*9880d681SAndroid Build Coastguard Worker SI.setOperand(2, TrueVal);
1230*9880d681SAndroid Build Coastguard Worker return &SI;
1231*9880d681SAndroid Build Coastguard Worker }
1232*9880d681SAndroid Build Coastguard Worker
1233*9880d681SAndroid Build Coastguard Worker if (VectorType* VecTy = dyn_cast<VectorType>(SelType)) {
1234*9880d681SAndroid Build Coastguard Worker unsigned VWidth = VecTy->getNumElements();
1235*9880d681SAndroid Build Coastguard Worker APInt UndefElts(VWidth, 0);
1236*9880d681SAndroid Build Coastguard Worker APInt AllOnesEltMask(APInt::getAllOnesValue(VWidth));
1237*9880d681SAndroid Build Coastguard Worker if (Value *V = SimplifyDemandedVectorElts(&SI, AllOnesEltMask, UndefElts)) {
1238*9880d681SAndroid Build Coastguard Worker if (V != &SI)
1239*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
1240*9880d681SAndroid Build Coastguard Worker return &SI;
1241*9880d681SAndroid Build Coastguard Worker }
1242*9880d681SAndroid Build Coastguard Worker
1243*9880d681SAndroid Build Coastguard Worker if (isa<ConstantAggregateZero>(CondVal)) {
1244*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, FalseVal);
1245*9880d681SAndroid Build Coastguard Worker }
1246*9880d681SAndroid Build Coastguard Worker }
1247*9880d681SAndroid Build Coastguard Worker
1248*9880d681SAndroid Build Coastguard Worker // See if we can determine the result of this select based on a dominating
1249*9880d681SAndroid Build Coastguard Worker // condition.
1250*9880d681SAndroid Build Coastguard Worker BasicBlock *Parent = SI.getParent();
1251*9880d681SAndroid Build Coastguard Worker if (BasicBlock *Dom = Parent->getSinglePredecessor()) {
1252*9880d681SAndroid Build Coastguard Worker auto *PBI = dyn_cast_or_null<BranchInst>(Dom->getTerminator());
1253*9880d681SAndroid Build Coastguard Worker if (PBI && PBI->isConditional() &&
1254*9880d681SAndroid Build Coastguard Worker PBI->getSuccessor(0) != PBI->getSuccessor(1) &&
1255*9880d681SAndroid Build Coastguard Worker (PBI->getSuccessor(0) == Parent || PBI->getSuccessor(1) == Parent)) {
1256*9880d681SAndroid Build Coastguard Worker bool CondIsFalse = PBI->getSuccessor(1) == Parent;
1257*9880d681SAndroid Build Coastguard Worker Optional<bool> Implication = isImpliedCondition(
1258*9880d681SAndroid Build Coastguard Worker PBI->getCondition(), SI.getCondition(), DL, CondIsFalse);
1259*9880d681SAndroid Build Coastguard Worker if (Implication) {
1260*9880d681SAndroid Build Coastguard Worker Value *V = *Implication ? TrueVal : FalseVal;
1261*9880d681SAndroid Build Coastguard Worker return replaceInstUsesWith(SI, V);
1262*9880d681SAndroid Build Coastguard Worker }
1263*9880d681SAndroid Build Coastguard Worker }
1264*9880d681SAndroid Build Coastguard Worker }
1265*9880d681SAndroid Build Coastguard Worker
1266*9880d681SAndroid Build Coastguard Worker return nullptr;
1267*9880d681SAndroid Build Coastguard Worker }
1268