@@ -73,81 +73,84 @@ Constant *llvm::getPredForFCmpCode(unsigned Code, Type *OpTy,
7373 return nullptr ;
7474}
7575
76- bool llvm::decomposeBitTestICmp (Value *LHS, Value *RHS,
77- CmpInst::Predicate & Pred,
78- Value *&X, APInt &Mask, bool LookThruTrunc) {
76+ std::optional<DecomposedBitTest>
77+ llvm::decomposeBitTestICmp (Value *LHS, Value *RHS, CmpInst::Predicate Pred,
78+ bool LookThruTrunc) {
7979 using namespace PatternMatch ;
8080
8181 const APInt *C;
8282 if (!match (RHS, m_APIntAllowPoison (C)))
83- return false ;
83+ return std:: nullopt ;
8484
85+ DecomposedBitTest Result;
8586 switch (Pred) {
8687 default :
87- return false ;
88+ return std:: nullopt ;
8889 case ICmpInst::ICMP_SLT:
8990 // X < 0 is equivalent to (X & SignMask) != 0.
9091 if (!C->isZero ())
91- return false ;
92- Mask = APInt::getSignMask (C->getBitWidth ());
93- Pred = ICmpInst::ICMP_NE;
92+ return std:: nullopt ;
93+ Result. Mask = APInt::getSignMask (C->getBitWidth ());
94+ Result. Pred = ICmpInst::ICMP_NE;
9495 break ;
9596 case ICmpInst::ICMP_SLE:
9697 // X <= -1 is equivalent to (X & SignMask) != 0.
9798 if (!C->isAllOnes ())
98- return false ;
99- Mask = APInt::getSignMask (C->getBitWidth ());
100- Pred = ICmpInst::ICMP_NE;
99+ return std:: nullopt ;
100+ Result. Mask = APInt::getSignMask (C->getBitWidth ());
101+ Result. Pred = ICmpInst::ICMP_NE;
101102 break ;
102103 case ICmpInst::ICMP_SGT:
103104 // X > -1 is equivalent to (X & SignMask) == 0.
104105 if (!C->isAllOnes ())
105- return false ;
106- Mask = APInt::getSignMask (C->getBitWidth ());
107- Pred = ICmpInst::ICMP_EQ;
106+ return std:: nullopt ;
107+ Result. Mask = APInt::getSignMask (C->getBitWidth ());
108+ Result. Pred = ICmpInst::ICMP_EQ;
108109 break ;
109110 case ICmpInst::ICMP_SGE:
110111 // X >= 0 is equivalent to (X & SignMask) == 0.
111112 if (!C->isZero ())
112- return false ;
113- Mask = APInt::getSignMask (C->getBitWidth ());
114- Pred = ICmpInst::ICMP_EQ;
113+ return std:: nullopt ;
114+ Result. Mask = APInt::getSignMask (C->getBitWidth ());
115+ Result. Pred = ICmpInst::ICMP_EQ;
115116 break ;
116117 case ICmpInst::ICMP_ULT:
117118 // X <u 2^n is equivalent to (X & ~(2^n-1)) == 0.
118119 if (!C->isPowerOf2 ())
119- return false ;
120- Mask = -*C;
121- Pred = ICmpInst::ICMP_EQ;
120+ return std:: nullopt ;
121+ Result. Mask = -*C;
122+ Result. Pred = ICmpInst::ICMP_EQ;
122123 break ;
123124 case ICmpInst::ICMP_ULE:
124125 // X <=u 2^n-1 is equivalent to (X & ~(2^n-1)) == 0.
125126 if (!(*C + 1 ).isPowerOf2 ())
126- return false ;
127- Mask = ~*C;
128- Pred = ICmpInst::ICMP_EQ;
127+ return std:: nullopt ;
128+ Result. Mask = ~*C;
129+ Result. Pred = ICmpInst::ICMP_EQ;
129130 break ;
130131 case ICmpInst::ICMP_UGT:
131132 // X >u 2^n-1 is equivalent to (X & ~(2^n-1)) != 0.
132133 if (!(*C + 1 ).isPowerOf2 ())
133- return false ;
134- Mask = ~*C;
135- Pred = ICmpInst::ICMP_NE;
134+ return std:: nullopt ;
135+ Result. Mask = ~*C;
136+ Result. Pred = ICmpInst::ICMP_NE;
136137 break ;
137138 case ICmpInst::ICMP_UGE:
138139 // X >=u 2^n is equivalent to (X & ~(2^n-1)) != 0.
139140 if (!C->isPowerOf2 ())
140- return false ;
141- Mask = -*C;
142- Pred = ICmpInst::ICMP_NE;
141+ return std:: nullopt ;
142+ Result. Mask = -*C;
143+ Result. Pred = ICmpInst::ICMP_NE;
143144 break ;
144145 }
145146
147+ Value *X;
146148 if (LookThruTrunc && match (LHS, m_Trunc (m_Value (X)))) {
147- Mask = Mask.zext (X->getType ()->getScalarSizeInBits ());
149+ Result.X = X;
150+ Result.Mask = Result.Mask .zext (X->getType ()->getScalarSizeInBits ());
148151 } else {
149- X = LHS;
152+ Result. X = LHS;
150153 }
151154
152- return true ;
155+ return Result ;
153156}
0 commit comments