Lines Matching +full:function +full:- +full:mask
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)
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
44 //===----------------------------------------------------------------------===//
73 bool runOnFunction(Function &F) override;
81 // (TDC operand, TDC mask, worthy flag) triples.
98 // Marks an instruction as converted - adds it to ConvertedInsts and adds
100 void converted(Instruction *I, Value *V, int Mask, bool Worthy) { in converted() argument
101 ConvertedInsts[I] = std::make_tuple(V, Mask, Worthy); in converted()
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()
179 { // -inf in convertFCmp()
197 { // -minnorm in convertFCmp()
207 // Construct the mask as a combination of the partial masks. in convertFCmp()
208 int Mask = 0; in convertFCmp() local
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()
224 Mask &= SystemZ::TDCMASK_PLUS; in convertFCmp()
225 Mask |= Mask >> 1; in convertFCmp()
226 Op0 = CI->getArgOperand(0); in convertFCmp()
233 converted(&I, Op0, Mask, Worthy); 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()
250 int Mask; in convertICmp() local
251 if (Pred == CmpInst::ICMP_SLT && Const->isZero()) { in convertICmp()
252 // icmp slt (bitcast X), 0 - set if sign bit true in convertICmp()
253 Mask = SystemZ::TDCMASK_MINUS; 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()
256 Mask = SystemZ::TDCMASK_PLUS; in convertICmp()
262 converted(&I, V, Mask, true); 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()
272 // Bail if the mask is not a constant. in convertICmp()
275 int Mask = MaskC->getZExtValue(); in convertICmp() local
276 Mask &= SystemZ::TDCMASK_ALL; 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()
281 Mask ^= SystemZ::TDCMASK_ALL; in convertICmp()
283 // An unknown comparison - ignore. in convertICmp()
287 converted(&I, V, Mask, false); in convertICmp()
299 int Mask; in convertLogicOp() local
302 Mask = Mask0 & Mask1; in convertLogicOp()
305 Mask = Mask0 | Mask1; in convertLogicOp()
308 Mask = Mask0 ^ Mask1; in convertLogicOp()
313 converted(&I, Op0, Mask, true); in convertLogicOp()
316 bool SystemZTDCPass::runOnFunction(Function &F) { in runOnFunction()
345 if (ConvertedInsts.count(dyn_cast<Instruction>(Op->getOperand(0))) && in runOnFunction()
346 ConvertedInsts.count(dyn_cast<Instruction>(Op->getOperand(1))) && in runOnFunction()
361 int Mask; in runOnFunction() local
363 std::tie(V, Mask, Worthy) = It.second; in runOnFunction()
364 if (!I->user_empty()) { in runOnFunction()
369 Function *TDCFunc = in runOnFunction()
370 Intrinsic::getDeclaration(&M, Intrinsic::s390_tdc, V->getType()); in runOnFunction()
372 Value *MaskVal = ConstantInt::get(Type::getInt64Ty(Ctx), Mask); 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()