Lines Matching +full:in +full:- +full:masks
1 //===-- SystemZTDC.cpp - Utilize Test Data Class instruction --------------===//
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
14 // 1: fcmp pred X, 0 -> tdc X, mask
15 // 2: fcmp pred X, +-inf -> tdc X, mask
16 // 3: fcmp pred X, +-minnorm -> tdc X, mask
17 // 4: tdc (fabs X), mask -> tdc X, newmask
18 // 5: icmp slt (bitcast float X to int), 0 -> tdc X, mask [ie. signbit]
19 // 6: icmp sgt (bitcast float X to int), -1 -> tdc X, mask
20 // 7: icmp ne/eq (call @llvm.s390.tdc.*(X, mask)) -> tdc X, mask/~mask
21 // 8: and i1 (tdc X, M1), (tdc X, M2) -> tdc X, (M1 & M2)
22 // 9: or i1 (tdc X, M1), (tdc X, M2) -> tdc X, (M1 | M2)
23 // 10: xor i1 (tdc X, M1), (tdc X, M2) -> tdc X, (M1 ^ M2)
25 // The pass works in 4 steps:
27 // 1. All fcmp and icmp instructions in a function are checked for a match
28 // with rules 1-3 and 5-7. Their TDC equivalents are stored in
32 // mapped are mapped according to rules 8-10. LogicOpsWorklist is used
39 // Instructions that match rules 1-3 are considered unworthy of conversion
41 // in the hopes of folding the result using rules 4 and 8-10 (likely removing
42 // the original comparison in the process).
44 //===----------------------------------------------------------------------===//
98 // Marks an instruction as converted - adds it to ConvertedInsts and adds
102 auto &M = *I->getFunction()->getParent(); in converted()
104 for (auto *U : I->users()) { in converted()
106 if (LI && LI->getType() == Type::getInt1Ty(Ctx) && in converted()
107 (LI->getOpcode() == Instruction::And || in converted()
108 LI->getOpcode() == Instruction::Or || in converted()
109 LI->getOpcode() == Instruction::Xor)) { in converted()
119 INITIALIZE_PASS(SystemZTDCPass, "systemz-tdc",
134 auto &Sem = Op0->getType()->getFltSemantics(); in convertFCmp()
140 if (Const->isZero()) { in convertFCmp()
143 } else if (Const->isInfinity()) { in convertFCmp()
145 WhichConst = Const->isNegative() ? 2 : 1; in convertFCmp()
146 } else if (Const->isExactlyValue(Smallest)) { in convertFCmp()
152 } else if (Const->isExactlyValue(NegSmallest)) { in convertFCmp()
162 // Partial masks to use for EQ, GT, LT, UN comparisons, respectively. in convertFCmp()
163 static const int Masks[][4] = { in convertFCmp() local
179 { // -inf in convertFCmp()
197 { // -minnorm in convertFCmp()
207 // Construct the mask as a combination of the partial masks. in convertFCmp()
210 Mask |= Masks[WhichConst][0]; in convertFCmp()
212 Mask |= Masks[WhichConst][1]; in convertFCmp()
214 Mask |= Masks[WhichConst][2]; in convertFCmp()
216 Mask |= Masks[WhichConst][3]; in convertFCmp()
221 Function *F = CI->getCalledFunction(); in convertFCmp()
222 if (F && F->getIntrinsicID() == Intrinsic::fabs) { in convertFCmp()
223 // Fold with fabs - adjust the mask appropriately. in convertFCmp()
226 Op0 = CI->getArgOperand(0); in convertFCmp()
245 if (!Cast->getSrcTy()->isFloatTy() && in convertICmp()
246 !Cast->getSrcTy()->isDoubleTy() && in convertICmp()
247 !Cast->getSrcTy()->isFP128Ty()) in convertICmp()
249 Value *V = Cast->getOperand(0); in convertICmp()
251 if (Pred == CmpInst::ICMP_SLT && Const->isZero()) { in convertICmp()
252 // icmp slt (bitcast X), 0 - set if sign bit true in convertICmp()
254 } else if (Pred == CmpInst::ICMP_SGT && Const->isMinusOne()) { in convertICmp()
255 // icmp sgt (bitcast X), -1 - set if sign bit false in convertICmp()
264 // Check if this is a pre-existing call of our tdc intrinsic. in convertICmp()
265 Function *F = CI->getCalledFunction(); in convertICmp()
266 if (!F || F->getIntrinsicID() != Intrinsic::s390_tdc) in convertICmp()
268 if (!Const->isZero()) in convertICmp()
270 Value *V = CI->getArgOperand(0); in convertICmp()
271 auto *MaskC = dyn_cast<ConstantInt>(CI->getArgOperand(1)); in convertICmp()
275 int Mask = MaskC->getZExtValue(); in convertICmp()
278 // icmp ne (call llvm.s390.tdc(...)), 0 -> simple TDC in convertICmp()
280 // icmp eq (call llvm.s390.tdc(...)), 0 -> TDC with inverted mask in convertICmp()
283 // An unknown comparison - ignore. in convertICmp()
311 llvm_unreachable("Unknown op in convertLogicOp"); in convertLogicOp()
345 if (ConvertedInsts.count(dyn_cast<Instruction>(Op->getOperand(0))) && in runOnFunction()
346 ConvertedInsts.count(dyn_cast<Instruction>(Op->getOperand(1))) && in runOnFunction()
351 // Time to actually replace the instructions. Do it in the reverse order in runOnFunction()
364 if (!I->user_empty()) { in runOnFunction()
370 Intrinsic::getDeclaration(&M, Intrinsic::s390_tdc, V->getType()); in runOnFunction()
375 I->replaceAllUsesWith(ICmp); in runOnFunction()
378 I->eraseFromParent(); in runOnFunction()
385 // We've actually done something - now clear misc accumulated junk (fabs, in runOnFunction()
388 if (I->user_empty()) in runOnFunction()
389 I->eraseFromParent(); in runOnFunction()