llvm.org GIT mirror llvm / fc52a9c
Recommit r310869, "[InstSimplify][InstCombine] Modify the interface of decomposeBitTestICmp and use it in the InstSimplify" This recommits r310869, with the moved files and no extra changes. Original commit message: This addresses a fixme in InstSimplify about using decomposeBitTest. This also fixes InstSimplify to handle ugt and ult compares too. I've modified the interface a little to return only the APInt version of the mask that InstSimplify needs. InstCombine now has a small wrapper routine to create a Constant out of it. I've also dropped the returning of 0 since InstSimplify doesn't need that. So InstCombine creates a zero constant itself. I also had to make decomposeBitTest support vectors since InstSimplify needs that. As InstSimplify can't use something from the Transforms library, I've moved the CmpInstAnalysis code to the Analysis library. Differential Revision: https://reviews.llvm.org/D36593 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@310889 91177308-0d34-0410-b5e6-96231b3b80d8 Craig Topper 2 years ago
9 changed file(s) with 224 addition(s) and 226 deletion(s). Raw diff Collapse all Expand all
0 //===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file holds routines to help analyse compare instructions
10 // and fold them into constants or other compare instructions
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_ANALYSIS_CMPINSTANALYSIS_H
15 #define LLVM_ANALYSIS_CMPINSTANALYSIS_H
16
17 #include "llvm/IR/InstrTypes.h"
18
19 namespace llvm {
20 class ICmpInst;
21 class Value;
22
23 /// Encode a icmp predicate into a three bit mask. These bits are carefully
24 /// arranged to allow folding of expressions such as:
25 ///
26 /// (A < B) | (A > B) --> (A != B)
27 ///
28 /// Note that this is only valid if the first and second predicates have the
29 /// same sign. It is illegal to do: (A u< B) | (A s> B)
30 ///
31 /// Three bits are used to represent the condition, as follows:
32 /// 0 A > B
33 /// 1 A == B
34 /// 2 A < B
35 ///
36 /// <=> Value Definition
37 /// 000 0 Always false
38 /// 001 1 A > B
39 /// 010 2 A == B
40 /// 011 3 A >= B
41 /// 100 4 A < B
42 /// 101 5 A != B
43 /// 110 6 A <= B
44 /// 111 7 Always true
45 ///
46 unsigned getICmpCode(const ICmpInst *ICI, bool InvertPred = false);
47
48 /// This is the complement of getICmpCode, which turns an opcode and two
49 /// operands into either a constant true or false, or the predicate for a new
50 /// ICmp instruction. The sign is passed in to determine which kind of
51 /// predicate to use in the new icmp instruction.
52 /// Non-NULL return value will be a true or false constant.
53 /// NULL return means a new ICmp is needed. The predicate for which is output
54 /// in NewICmpPred.
55 Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
56 CmpInst::Predicate &NewICmpPred);
57
58 /// Return true if both predicates match sign or if at least one of them is an
59 /// equality comparison (which is signless).
60 bool PredicatesFoldable(CmpInst::Predicate p1, CmpInst::Predicate p2);
61
62 /// Decompose an icmp into the form ((X & Mask) pred 0) if possible. The
63 /// returned predicate is either == or !=. Returns false if decomposition
64 /// fails.
65 bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred,
66 Value *&X, APInt &Mask);
67
68 } // end namespace llvm
69
70 #endif
+0
-70
include/llvm/Transforms/Utils/CmpInstAnalysis.h less more
None //===-- CmpInstAnalysis.h - Utils to help fold compare insts ----*- C++ -*-===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file holds routines to help analyse compare instructions
10 // and fold them into constants or other compare instructions
11 //
12 //===----------------------------------------------------------------------===//
13
14 #ifndef LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
15 #define LLVM_TRANSFORMS_UTILS_CMPINSTANALYSIS_H
16
17 #include "llvm/IR/InstrTypes.h"
18
19 namespace llvm {
20 class ICmpInst;
21 class Value;
22
23 /// Encode a icmp predicate into a three bit mask. These bits are carefully
24 /// arranged to allow folding of expressions such as:
25 ///
26 /// (A < B) | (A > B) --> (A != B)
27 ///
28 /// Note that this is only valid if the first and second predicates have the
29 /// same sign. It is illegal to do: (A u< B) | (A s> B)
30 ///
31 /// Three bits are used to represent the condition, as follows:
32 /// 0 A > B
33 /// 1 A == B
34 /// 2 A < B
35 ///
36 /// <=> Value Definition
37 /// 000 0 Always false
38 /// 001 1 A > B
39 /// 010 2 A == B
40 /// 011 3 A >= B
41 /// 100 4 A < B
42 /// 101 5 A != B
43 /// 110 6 A <= B
44 /// 111 7 Always true
45 ///
46 unsigned getICmpCode(const ICmpInst *ICI, bool InvertPred = false);
47
48 /// This is the complement of getICmpCode, which turns an opcode and two
49 /// operands into either a constant true or false, or the predicate for a new
50 /// ICmp instruction. The sign is passed in to determine which kind of
51 /// predicate to use in the new icmp instruction.
52 /// Non-NULL return value will be a true or false constant.
53 /// NULL return means a new ICmp is needed. The predicate for which is output
54 /// in NewICmpPred.
55 Value *getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
56 CmpInst::Predicate &NewICmpPred);
57
58 /// Return true if both predicates match sign or if at least one of them is an
59 /// equality comparison (which is signless).
60 bool PredicatesFoldable(CmpInst::Predicate p1, CmpInst::Predicate p2);
61
62 /// Decompose an icmp into the form ((X & Y) pred Z) if possible. The returned
63 /// predicate is either == or !=. Returns false if decomposition fails.
64 bool decomposeBitTestICmp(const ICmpInst *I, CmpInst::Predicate &Pred,
65 Value *&X, Value *&Y, Value *&Z);
66
67 } // end namespace llvm
68
69 #endif
1717 CallGraphSCCPass.cpp
1818 CallPrinter.cpp
1919 CaptureTracking.cpp
20 CmpInstAnalysis.cpp
2021 CostModel.cpp
2122 CodeMetrics.cpp
2223 ConstantFolding.cpp
0 //===- CmpInstAnalysis.cpp - Utils to help fold compares ---------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file holds routines to help analyse compare instructions
10 // and fold them into constants or other compare instructions
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Analysis/CmpInstAnalysis.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/Instructions.h"
17 #include "llvm/IR/PatternMatch.h"
18
19 using namespace llvm;
20
21 unsigned llvm::getICmpCode(const ICmpInst *ICI, bool InvertPred) {
22 ICmpInst::Predicate Pred = InvertPred ? ICI->getInversePredicate()
23 : ICI->getPredicate();
24 switch (Pred) {
25 // False -> 0
26 case ICmpInst::ICMP_UGT: return 1; // 001
27 case ICmpInst::ICMP_SGT: return 1; // 001
28 case ICmpInst::ICMP_EQ: return 2; // 010
29 case ICmpInst::ICMP_UGE: return 3; // 011
30 case ICmpInst::ICMP_SGE: return 3; // 011
31 case ICmpInst::ICMP_ULT: return 4; // 100
32 case ICmpInst::ICMP_SLT: return 4; // 100
33 case ICmpInst::ICMP_NE: return 5; // 101
34 case ICmpInst::ICMP_ULE: return 6; // 110
35 case ICmpInst::ICMP_SLE: return 6; // 110
36 // True -> 7
37 default:
38 llvm_unreachable("Invalid ICmp predicate!");
39 }
40 }
41
42 Value *llvm::getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
43 CmpInst::Predicate &NewICmpPred) {
44 switch (Code) {
45 default: llvm_unreachable("Illegal ICmp code!");
46 case 0: // False.
47 return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
48 case 1: NewICmpPred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
49 case 2: NewICmpPred = ICmpInst::ICMP_EQ; break;
50 case 3: NewICmpPred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
51 case 4: NewICmpPred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
52 case 5: NewICmpPred = ICmpInst::ICMP_NE; break;
53 case 6: NewICmpPred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
54 case 7: // True.
55 return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 1);
56 }
57 return nullptr;
58 }
59
60 bool llvm::PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
61 return (CmpInst::isSigned(p1) == CmpInst::isSigned(p2)) ||
62 (CmpInst::isSigned(p1) && ICmpInst::isEquality(p2)) ||
63 (CmpInst::isSigned(p2) && ICmpInst::isEquality(p1));
64 }
65
66 bool llvm::decomposeBitTestICmp(Value *LHS, Value *RHS,
67 CmpInst::Predicate &Pred,
68 Value *&X, APInt &Mask) {
69 const APInt *C;
70 if (!match(RHS, PatternMatch::m_APInt(C)))
71 return false;
72
73 switch (Pred) {
74 default:
75 return false;
76 case ICmpInst::ICMP_SLT:
77 // X < 0 is equivalent to (X & SignMask) != 0.
78 if (!C->isNullValue())
79 return false;
80 Mask = APInt::getSignMask(C->getBitWidth());
81 Pred = ICmpInst::ICMP_NE;
82 break;
83 case ICmpInst::ICMP_SGT:
84 // X > -1 is equivalent to (X & SignMask) == 0.
85 if (!C->isAllOnesValue())
86 return false;
87 Mask = APInt::getSignMask(C->getBitWidth());
88 Pred = ICmpInst::ICMP_EQ;
89 break;
90 case ICmpInst::ICMP_ULT:
91 // X
92 if (!C->isPowerOf2())
93 return false;
94 Mask = -*C;
95 Pred = ICmpInst::ICMP_EQ;
96 break;
97 case ICmpInst::ICMP_UGT:
98 // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
99 if (!(*C + 1).isPowerOf2())
100 return false;
101 Mask = ~*C;
102 Pred = ICmpInst::ICMP_NE;
103 break;
104 }
105
106 X = LHS;
107 return true;
108 }
2222 #include "llvm/Analysis/AliasAnalysis.h"
2323 #include "llvm/Analysis/AssumptionCache.h"
2424 #include "llvm/Analysis/CaptureTracking.h"
25 #include "llvm/Analysis/CmpInstAnalysis.h"
2526 #include "llvm/Analysis/ConstantFolding.h"
2627 #include "llvm/Analysis/LoopAnalysisManager.h"
2728 #include "llvm/Analysis/MemoryBuiltins.h"
36193620
36203621 /// An alternative way to test if a bit is set or not uses sgt/slt instead of
36213622 /// eq/ne.
3622 static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *TrueVal,
3623 Value *FalseVal,
3624 bool TrueWhenUnset) {
3623 static Value *simplifySelectWithFakeICmpEq(Value *CmpLHS, Value *CmpRHS,
3624 ICmpInst::Predicate Pred,
3625 Value *TrueVal, Value *FalseVal) {
3626 Value *X;
3627 APInt Mask;
3628 if (!decomposeBitTestICmp(CmpLHS, CmpRHS, Pred, X, Mask))
3629 return nullptr;
3630
36253631 unsigned BitWidth = TrueVal->getType()->getScalarSizeInBits();
36263632 if (!BitWidth)
36273633 return nullptr;
36283634
3629 APInt MinSignedValue;
3630 Value *X;
3631 if (match(CmpLHS, m_Trunc(m_Value(X))) && (X == TrueVal || X == FalseVal)) {
3635 Value *ExtX;
3636 if (match(X, m_Trunc(m_Value(ExtX))) &&
3637 (ExtX == TrueVal || ExtX == FalseVal)) {
36323638 // icmp slt (trunc X), 0 <--> icmp ne (and X, C), 0
36333639 // icmp sgt (trunc X), -1 <--> icmp eq (and X, C), 0
3634 unsigned DestSize = CmpLHS->getType()->getScalarSizeInBits();
3635 MinSignedValue = APInt::getSignedMinValue(DestSize).zext(BitWidth);
3636 } else {
3637 // icmp slt X, 0 <--> icmp ne (and X, C), 0
3638 // icmp sgt X, -1 <--> icmp eq (and X, C), 0
3639 X = CmpLHS;
3640 MinSignedValue = APInt::getSignedMinValue(BitWidth);
3641 }
3642
3643 if (Value *V = simplifySelectBitTest(TrueVal, FalseVal, X, &MinSignedValue,
3644 TrueWhenUnset))
3645 return V;
3646
3647 return nullptr;
3640 X = ExtX;
3641 Mask = Mask.zext(BitWidth);
3642 }
3643
3644 return simplifySelectBitTest(TrueVal, FalseVal, X, &Mask,
3645 Pred == ICmpInst::ICMP_EQ);
36483646 }
36493647
36503648 /// Try to simplify a select instruction when its condition operand is an
36573655 if (!match(CondVal, m_ICmp(Pred, m_Value(CmpLHS), m_Value(CmpRHS))))
36583656 return nullptr;
36593657
3660 // FIXME: This code is nearly duplicated in InstCombine. Using/refactoring
3661 // decomposeBitTestICmp() might help.
3662 // FIXME this should support ICMP_SLE/SGE forms as well
36633658 if (ICmpInst::isEquality(Pred) && match(CmpRHS, m_Zero())) {
36643659 Value *X;
36653660 const APInt *Y;
36673662 if (Value *V = simplifySelectBitTest(TrueVal, FalseVal, X, Y,
36683663 Pred == ICmpInst::ICMP_EQ))
36693664 return V;
3670 } else if (Pred == ICmpInst::ICMP_SLT && match(CmpRHS, m_Zero())) {
3671 // Comparing signed-less-than 0 checks if the sign bit is set.
3672 if (Value *V = simplifySelectWithFakeICmpEq(CmpLHS, TrueVal, FalseVal,
3673 false))
3674 return V;
3675 } else if (Pred == ICmpInst::ICMP_SGT && match(CmpRHS, m_AllOnes())) {
3676 // Comparing signed-greater-than -1 checks if the sign bit is not set.
3677 if (Value *V = simplifySelectWithFakeICmpEq(CmpLHS, TrueVal, FalseVal,
3678 true))
3679 return V;
3680 }
3665 }
3666
3667 // Check for other compares that behave like bit test.
3668 if (Value *V = simplifySelectWithFakeICmpEq(CmpLHS, CmpRHS, Pred,
3669 TrueVal, FalseVal))
3670 return V;
36813671
36823672 if (CondVal->hasOneUse()) {
36833673 const APInt *C;
1111 //===----------------------------------------------------------------------===//
1212
1313 #include "InstCombineInternal.h"
14 #include "llvm/Analysis/CmpInstAnalysis.h"
1415 #include "llvm/Analysis/InstructionSimplify.h"
1516 #include "llvm/IR/ConstantRange.h"
1617 #include "llvm/IR/Intrinsics.h"
1718 #include "llvm/IR/PatternMatch.h"
18 #include "llvm/Transforms/Utils/CmpInstAnalysis.h"
1919 #include "llvm/Transforms/Utils/Local.h"
2020 using namespace llvm;
2121 using namespace PatternMatch;
291291 return NewMask;
292292 }
293293
294 // Adapts the external decomposeBitTestICmp for local use.
295 static bool decomposeBitTestICmp(Value *LHS, Value *RHS, CmpInst::Predicate &Pred,
296 Value *&X, Value *&Y, Value *&Z) {
297 APInt Mask;
298 if (!llvm::decomposeBitTestICmp(LHS, RHS, Pred, X, Mask))
299 return false;
300
301 Y = ConstantInt::get(LHS->getType(), Mask);
302 Z = ConstantInt::get(RHS->getType(), 0);
303 return true;
304 }
305
294306 /// Handle (icmp(A & B) ==/!= C) &/| (icmp(A & D) ==/!= E).
295307 /// Return the set of pattern classes (from MaskedICmpType) that both LHS and
296308 /// RHS satisfy.
315327 Value *L2 = LHS->getOperand(1);
316328 Value *L11, *L12, *L21, *L22;
317329 // Check whether the icmp can be decomposed into a bit test.
318 if (decomposeBitTestICmp(LHS, PredL, L11, L12, L2)) {
330 if (decomposeBitTestICmp(L1, L2, PredL, L11, L12, L2)) {
319331 L21 = L22 = L1 = nullptr;
320332 } else {
321333 // Look for ANDs in the LHS icmp.
346358 Value *R2 = RHS->getOperand(1);
347359 Value *R11, *R12;
348360 bool Ok = false;
349 if (decomposeBitTestICmp(RHS, PredR, R11, R12, R2)) {
361 if (decomposeBitTestICmp(R1, R2, PredR, R11, R12, R2)) {
350362 if (R11 == L11 || R11 == L12 || R11 == L21 || R11 == L22) {
351363 A = R11;
352364 D = R12;
66 BypassSlowDivision.cpp
77 CloneFunction.cpp
88 CloneModule.cpp
9 CmpInstAnalysis.cpp
109 CodeExtractor.cpp
1110 CtorUtils.cpp
1211 DemoteRegToStack.cpp
+0
-108
lib/Transforms/Utils/CmpInstAnalysis.cpp less more
None //===- CmpInstAnalysis.cpp - Utils to help fold compares ---------------===//
1 //
2 // The LLVM Compiler Infrastructure
3 //
4 // This file is distributed under the University of Illinois Open Source
5 // License. See LICENSE.TXT for details.
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file holds routines to help analyse compare instructions
10 // and fold them into constants or other compare instructions
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/Transforms/Utils/CmpInstAnalysis.h"
15 #include "llvm/IR/Constants.h"
16 #include "llvm/IR/Instructions.h"
17
18 using namespace llvm;
19
20 unsigned llvm::getICmpCode(const ICmpInst *ICI, bool InvertPred) {
21 ICmpInst::Predicate Pred = InvertPred ? ICI->getInversePredicate()
22 : ICI->getPredicate();
23 switch (Pred) {
24 // False -> 0
25 case ICmpInst::ICMP_UGT: return 1; // 001
26 case ICmpInst::ICMP_SGT: return 1; // 001
27 case ICmpInst::ICMP_EQ: return 2; // 010
28 case ICmpInst::ICMP_UGE: return 3; // 011
29 case ICmpInst::ICMP_SGE: return 3; // 011
30 case ICmpInst::ICMP_ULT: return 4; // 100
31 case ICmpInst::ICMP_SLT: return 4; // 100
32 case ICmpInst::ICMP_NE: return 5; // 101
33 case ICmpInst::ICMP_ULE: return 6; // 110
34 case ICmpInst::ICMP_SLE: return 6; // 110
35 // True -> 7
36 default:
37 llvm_unreachable("Invalid ICmp predicate!");
38 }
39 }
40
41 Value *llvm::getICmpValue(bool Sign, unsigned Code, Value *LHS, Value *RHS,
42 CmpInst::Predicate &NewICmpPred) {
43 switch (Code) {
44 default: llvm_unreachable("Illegal ICmp code!");
45 case 0: // False.
46 return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 0);
47 case 1: NewICmpPred = Sign ? ICmpInst::ICMP_SGT : ICmpInst::ICMP_UGT; break;
48 case 2: NewICmpPred = ICmpInst::ICMP_EQ; break;
49 case 3: NewICmpPred = Sign ? ICmpInst::ICMP_SGE : ICmpInst::ICMP_UGE; break;
50 case 4: NewICmpPred = Sign ? ICmpInst::ICMP_SLT : ICmpInst::ICMP_ULT; break;
51 case 5: NewICmpPred = ICmpInst::ICMP_NE; break;
52 case 6: NewICmpPred = Sign ? ICmpInst::ICMP_SLE : ICmpInst::ICMP_ULE; break;
53 case 7: // True.
54 return ConstantInt::get(CmpInst::makeCmpResultType(LHS->getType()), 1);
55 }
56 return nullptr;
57 }
58
59 bool llvm::PredicatesFoldable(ICmpInst::Predicate p1, ICmpInst::Predicate p2) {
60 return (CmpInst::isSigned(p1) == CmpInst::isSigned(p2)) ||
61 (CmpInst::isSigned(p1) && ICmpInst::isEquality(p2)) ||
62 (CmpInst::isSigned(p2) && ICmpInst::isEquality(p1));
63 }
64
65 bool llvm::decomposeBitTestICmp(const ICmpInst *I, CmpInst::Predicate &Pred,
66 Value *&X, Value *&Y, Value *&Z) {
67 ConstantInt *C = dyn_cast(I->getOperand(1));
68 if (!C)
69 return false;
70
71 switch (I->getPredicate()) {
72 default:
73 return false;
74 case ICmpInst::ICMP_SLT:
75 // X < 0 is equivalent to (X & SignMask) != 0.
76 if (!C->isZero())
77 return false;
78 Y = ConstantInt::get(I->getContext(), APInt::getSignMask(C->getBitWidth()));
79 Pred = ICmpInst::ICMP_NE;
80 break;
81 case ICmpInst::ICMP_SGT:
82 // X > -1 is equivalent to (X & SignMask) == 0.
83 if (!C->isMinusOne())
84 return false;
85 Y = ConstantInt::get(I->getContext(), APInt::getSignMask(C->getBitWidth()));
86 Pred = ICmpInst::ICMP_EQ;
87 break;
88 case ICmpInst::ICMP_ULT:
89 // X
90 if (!C->getValue().isPowerOf2())
91 return false;
92 Y = ConstantInt::get(I->getContext(), -C->getValue());
93 Pred = ICmpInst::ICMP_EQ;
94 break;
95 case ICmpInst::ICMP_UGT:
96 // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
97 if (!(C->getValue() + 1).isPowerOf2())
98 return false;
99 Y = ConstantInt::get(I->getContext(), ~C->getValue());
100 Pred = ICmpInst::ICMP_NE;
101 break;
102 }
103
104 X = I->getOperand(0);
105 Z = ConstantInt::getNullValue(C->getType());
106 return true;
107 }
159159 ret <2 x i8> %sel
160160 }
161161
162 ; TODO: we should be able to simplify this
163162 define i32 @test12(i32 %X) {
164163 ; CHECK-LABEL: @test12(
165 ; CHECK-NEXT: [[CMP:%.*]] = icmp ult i32 [[X:%.*]], 4
166 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 3
167 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[X]], i32 [[AND]]
168 ; CHECK-NEXT: ret i32 [[COND]]
164 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
165 ; CHECK-NEXT: ret i32 [[AND]]
169166 ;
170167 %cmp = icmp ult i32 %X, 4
171168 %and = and i32 %X, 3
188185 ret i32 %cond
189186 }
190187
191 ; TODO: we should be able to simplify this
192188 define i32 @test13(i32 %X) {
193189 ; CHECK-LABEL: @test13(
194 ; CHECK-NEXT: [[CMP:%.*]] = icmp ugt i32 [[X:%.*]], 3
195 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X]], 3
196 ; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 [[AND]], i32 [[X]]
197 ; CHECK-NEXT: ret i32 [[COND]]
190 ; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 3
191 ; CHECK-NEXT: ret i32 [[AND]]
198192 ;
199193 %cmp = icmp ugt i32 %X, 3
200194 %and = and i32 %X, 3