1//===-- X86InstCombineIntrinsic.cpp - X86 specific InstCombine pass -------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9/// This file implements a TargetTransformInfo analysis pass specific to the
10/// X86 target machine. It uses the target's detailed information to provide
11/// more precise answers to certain TTI queries, while letting the target
12/// independent and default TTI implementations handle the rest.
13///
14//===----------------------------------------------------------------------===//
15
16#include "X86TargetTransformInfo.h"
17#include "llvm/IR/IntrinsicInst.h"
18#include "llvm/IR/IntrinsicsX86.h"
19#include "llvm/Support/KnownBits.h"
20#include "llvm/Transforms/InstCombine/InstCombiner.h"
21#include <optional>
22
23using namespace llvm;
24using namespace llvm::PatternMatch;
25
26#define DEBUG_TYPE "x86tti"
27
28/// Return a constant boolean vector that has true elements in all positions
29/// where the input constant data vector has an element with the sign bit set.
30static Constant *getNegativeIsTrueBoolVec(Constant *V, const DataLayout &DL) {
31 VectorType *IntTy = VectorType::getInteger(VTy: cast<VectorType>(Val: V->getType()));
32 V = ConstantExpr::getBitCast(C: V, Ty: IntTy);
33 V = ConstantFoldCompareInstOperands(Predicate: CmpInst::ICMP_SGT,
34 LHS: Constant::getNullValue(Ty: IntTy), RHS: V, DL);
35 assert(V && "Vector must be foldable");
36 return V;
37}
38
39/// Convert the x86 XMM integer vector mask to a vector of bools based on
40/// each element's most significant bit (the sign bit).
41static Value *getBoolVecFromMask(Value *Mask, const DataLayout &DL) {
42 // Fold Constant Mask.
43 if (isa<ConstantInt, ConstantFP, ConstantDataVector>(Val: Mask))
44 return getNegativeIsTrueBoolVec(V: cast<Constant>(Val: Mask), DL);
45
46 // Mask was extended from a boolean vector.
47 Value *ExtMask;
48 if (match(V: Mask, P: m_SExt(Op: m_Value(V&: ExtMask))) &&
49 ExtMask->getType()->isIntOrIntVectorTy(BitWidth: 1))
50 return ExtMask;
51
52 return nullptr;
53}
54
55// TODO: If the x86 backend knew how to convert a bool vector mask back to an
56// XMM register mask efficiently, we could transform all x86 masked intrinsics
57// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
58static Instruction *simplifyX86MaskedLoad(IntrinsicInst &II, InstCombiner &IC) {
59 Value *Ptr = II.getOperand(i_nocapture: 0);
60 Value *Mask = II.getOperand(i_nocapture: 1);
61 Constant *ZeroVec = Constant::getNullValue(Ty: II.getType());
62
63 // Zero Mask - masked load instruction creates a zero vector.
64 if (isa<ConstantAggregateZero>(Val: Mask))
65 return IC.replaceInstUsesWith(I&: II, V: ZeroVec);
66
67 // The mask is constant or extended from a bool vector. Convert this x86
68 // intrinsic to the LLVM intrinsic to allow target-independent optimizations.
69 if (Value *BoolMask = getBoolVecFromMask(Mask, DL: IC.getDataLayout())) {
70 // The pass-through vector for an x86 masked load is a zero vector.
71 CallInst *NewMaskedLoad = IC.Builder.CreateMaskedLoad(
72 Ty: II.getType(), Ptr, Alignment: Align(1), Mask: BoolMask, PassThru: ZeroVec);
73 return IC.replaceInstUsesWith(I&: II, V: NewMaskedLoad);
74 }
75
76 return nullptr;
77}
78
79// TODO: If the x86 backend knew how to convert a bool vector mask back to an
80// XMM register mask efficiently, we could transform all x86 masked intrinsics
81// to LLVM masked intrinsics and remove the x86 masked intrinsic defs.
82static bool simplifyX86MaskedStore(IntrinsicInst &II, InstCombiner &IC) {
83 Value *Ptr = II.getOperand(i_nocapture: 0);
84 Value *Mask = II.getOperand(i_nocapture: 1);
85 Value *Vec = II.getOperand(i_nocapture: 2);
86
87 // Zero Mask - this masked store instruction does nothing.
88 if (isa<ConstantAggregateZero>(Val: Mask)) {
89 IC.eraseInstFromFunction(I&: II);
90 return true;
91 }
92
93 // The SSE2 version is too weird (eg, unaligned but non-temporal) to do
94 // anything else at this level.
95 if (II.getIntrinsicID() == Intrinsic::x86_sse2_maskmov_dqu)
96 return false;
97
98 // The mask is constant or extended from a bool vector. Convert this x86
99 // intrinsic to the LLVM intrinsic to allow target-independent optimizations.
100 if (Value *BoolMask = getBoolVecFromMask(Mask, DL: IC.getDataLayout())) {
101 unsigned AddrSpace = cast<PointerType>(Val: Ptr->getType())->getAddressSpace();
102 PointerType *VecPtrTy = PointerType::get(C&: Vec->getContext(), AddressSpace: AddrSpace);
103 Value *PtrCast = IC.Builder.CreateBitCast(V: Ptr, DestTy: VecPtrTy, Name: "castvec");
104
105 IC.Builder.CreateMaskedStore(Val: Vec, Ptr: PtrCast, Alignment: Align(1), Mask: BoolMask);
106
107 // 'Replace uses' doesn't work for stores. Erase the original masked store.
108 IC.eraseInstFromFunction(I&: II);
109 return true;
110 }
111
112 return false;
113}
114
115static Value *simplifyX86immShift(const IntrinsicInst &II,
116 InstCombiner::BuilderTy &Builder) {
117 bool LogicalShift = false;
118 bool ShiftLeft = false;
119 bool IsImm = false;
120
121 switch (II.getIntrinsicID()) {
122 default:
123 llvm_unreachable("Unexpected intrinsic!");
124 case Intrinsic::x86_sse2_psrai_d:
125 case Intrinsic::x86_sse2_psrai_w:
126 case Intrinsic::x86_avx2_psrai_d:
127 case Intrinsic::x86_avx2_psrai_w:
128 case Intrinsic::x86_avx512_psrai_q_128:
129 case Intrinsic::x86_avx512_psrai_q_256:
130 case Intrinsic::x86_avx512_psrai_d_512:
131 case Intrinsic::x86_avx512_psrai_q_512:
132 case Intrinsic::x86_avx512_psrai_w_512:
133 IsImm = true;
134 [[fallthrough]];
135 case Intrinsic::x86_sse2_psra_d:
136 case Intrinsic::x86_sse2_psra_w:
137 case Intrinsic::x86_avx2_psra_d:
138 case Intrinsic::x86_avx2_psra_w:
139 case Intrinsic::x86_avx512_psra_q_128:
140 case Intrinsic::x86_avx512_psra_q_256:
141 case Intrinsic::x86_avx512_psra_d_512:
142 case Intrinsic::x86_avx512_psra_q_512:
143 case Intrinsic::x86_avx512_psra_w_512:
144 LogicalShift = false;
145 ShiftLeft = false;
146 break;
147 case Intrinsic::x86_sse2_psrli_d:
148 case Intrinsic::x86_sse2_psrli_q:
149 case Intrinsic::x86_sse2_psrli_w:
150 case Intrinsic::x86_avx2_psrli_d:
151 case Intrinsic::x86_avx2_psrli_q:
152 case Intrinsic::x86_avx2_psrli_w:
153 case Intrinsic::x86_avx512_psrli_d_512:
154 case Intrinsic::x86_avx512_psrli_q_512:
155 case Intrinsic::x86_avx512_psrli_w_512:
156 IsImm = true;
157 [[fallthrough]];
158 case Intrinsic::x86_sse2_psrl_d:
159 case Intrinsic::x86_sse2_psrl_q:
160 case Intrinsic::x86_sse2_psrl_w:
161 case Intrinsic::x86_avx2_psrl_d:
162 case Intrinsic::x86_avx2_psrl_q:
163 case Intrinsic::x86_avx2_psrl_w:
164 case Intrinsic::x86_avx512_psrl_d_512:
165 case Intrinsic::x86_avx512_psrl_q_512:
166 case Intrinsic::x86_avx512_psrl_w_512:
167 LogicalShift = true;
168 ShiftLeft = false;
169 break;
170 case Intrinsic::x86_sse2_pslli_d:
171 case Intrinsic::x86_sse2_pslli_q:
172 case Intrinsic::x86_sse2_pslli_w:
173 case Intrinsic::x86_avx2_pslli_d:
174 case Intrinsic::x86_avx2_pslli_q:
175 case Intrinsic::x86_avx2_pslli_w:
176 case Intrinsic::x86_avx512_pslli_d_512:
177 case Intrinsic::x86_avx512_pslli_q_512:
178 case Intrinsic::x86_avx512_pslli_w_512:
179 IsImm = true;
180 [[fallthrough]];
181 case Intrinsic::x86_sse2_psll_d:
182 case Intrinsic::x86_sse2_psll_q:
183 case Intrinsic::x86_sse2_psll_w:
184 case Intrinsic::x86_avx2_psll_d:
185 case Intrinsic::x86_avx2_psll_q:
186 case Intrinsic::x86_avx2_psll_w:
187 case Intrinsic::x86_avx512_psll_d_512:
188 case Intrinsic::x86_avx512_psll_q_512:
189 case Intrinsic::x86_avx512_psll_w_512:
190 LogicalShift = true;
191 ShiftLeft = true;
192 break;
193 }
194 assert((LogicalShift || !ShiftLeft) && "Only logical shifts can shift left");
195
196 Value *Vec = II.getArgOperand(i: 0);
197 Value *Amt = II.getArgOperand(i: 1);
198 auto *VT = cast<FixedVectorType>(Val: Vec->getType());
199 Type *SVT = VT->getElementType();
200 Type *AmtVT = Amt->getType();
201 unsigned VWidth = VT->getNumElements();
202 unsigned BitWidth = SVT->getPrimitiveSizeInBits();
203
204 // If the shift amount is guaranteed to be in-range we can replace it with a
205 // generic shift. If its guaranteed to be out of range, logical shifts combine
206 // to zero and arithmetic shifts are clamped to (BitWidth - 1).
207 if (IsImm) {
208 assert(AmtVT->isIntegerTy(32) && "Unexpected shift-by-immediate type");
209 KnownBits KnownAmtBits =
210 llvm::computeKnownBits(V: Amt, DL: II.getDataLayout());
211 if (KnownAmtBits.getMaxValue().ult(RHS: BitWidth)) {
212 Amt = Builder.CreateZExtOrTrunc(V: Amt, DestTy: SVT);
213 Amt = Builder.CreateVectorSplat(NumElts: VWidth, V: Amt);
214 return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(LHS: Vec, RHS: Amt)
215 : Builder.CreateLShr(LHS: Vec, RHS: Amt))
216 : Builder.CreateAShr(LHS: Vec, RHS: Amt));
217 }
218 if (KnownAmtBits.getMinValue().uge(RHS: BitWidth)) {
219 if (LogicalShift)
220 return ConstantAggregateZero::get(Ty: VT);
221 Amt = ConstantInt::get(Ty: SVT, V: BitWidth - 1);
222 return Builder.CreateAShr(LHS: Vec, RHS: Builder.CreateVectorSplat(NumElts: VWidth, V: Amt));
223 }
224 } else {
225 // Ensure the first element has an in-range value and the rest of the
226 // elements in the bottom 64 bits are zero.
227 assert(AmtVT->isVectorTy() && AmtVT->getPrimitiveSizeInBits() == 128 &&
228 cast<VectorType>(AmtVT)->getElementType() == SVT &&
229 "Unexpected shift-by-scalar type");
230 unsigned NumAmtElts = cast<FixedVectorType>(Val: AmtVT)->getNumElements();
231 APInt DemandedLower = APInt::getOneBitSet(numBits: NumAmtElts, BitNo: 0);
232 APInt DemandedUpper = APInt::getBitsSet(numBits: NumAmtElts, loBit: 1, hiBit: NumAmtElts / 2);
233 KnownBits KnownLowerBits = llvm::computeKnownBits(
234 V: Amt, DemandedElts: DemandedLower, Q: II.getDataLayout());
235 KnownBits KnownUpperBits = llvm::computeKnownBits(
236 V: Amt, DemandedElts: DemandedUpper, Q: II.getDataLayout());
237 if (KnownLowerBits.getMaxValue().ult(RHS: BitWidth) &&
238 (DemandedUpper.isZero() || KnownUpperBits.isZero())) {
239 SmallVector<int, 16> ZeroSplat(VWidth, 0);
240 Amt = Builder.CreateShuffleVector(V: Amt, Mask: ZeroSplat);
241 return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(LHS: Vec, RHS: Amt)
242 : Builder.CreateLShr(LHS: Vec, RHS: Amt))
243 : Builder.CreateAShr(LHS: Vec, RHS: Amt));
244 }
245 }
246
247 // Simplify if count is constant vector.
248 auto *CDV = dyn_cast<ConstantDataVector>(Val: Amt);
249 if (!CDV)
250 return nullptr;
251
252 // SSE2/AVX2 uses all the first 64-bits of the 128-bit vector
253 // operand to compute the shift amount.
254 assert(AmtVT->isVectorTy() && AmtVT->getPrimitiveSizeInBits() == 128 &&
255 cast<VectorType>(AmtVT)->getElementType() == SVT &&
256 "Unexpected shift-by-scalar type");
257
258 // Concatenate the sub-elements to create the 64-bit value.
259 APInt Count(64, 0);
260 for (unsigned i = 0, NumSubElts = 64 / BitWidth; i != NumSubElts; ++i) {
261 unsigned SubEltIdx = (NumSubElts - 1) - i;
262 auto *SubElt = cast<ConstantInt>(Val: CDV->getElementAsConstant(i: SubEltIdx));
263 Count <<= BitWidth;
264 Count |= SubElt->getValue().zextOrTrunc(width: 64);
265 }
266
267 // If shift-by-zero then just return the original value.
268 if (Count.isZero())
269 return Vec;
270
271 // Handle cases when Shift >= BitWidth.
272 if (Count.uge(RHS: BitWidth)) {
273 // If LogicalShift - just return zero.
274 if (LogicalShift)
275 return ConstantAggregateZero::get(Ty: VT);
276
277 // If ArithmeticShift - clamp Shift to (BitWidth - 1).
278 Count = APInt(64, BitWidth - 1);
279 }
280
281 // Get a constant vector of the same type as the first operand.
282 auto ShiftAmt = ConstantInt::get(Ty: SVT, V: Count.zextOrTrunc(width: BitWidth));
283 auto ShiftVec = Builder.CreateVectorSplat(NumElts: VWidth, V: ShiftAmt);
284
285 if (ShiftLeft)
286 return Builder.CreateShl(LHS: Vec, RHS: ShiftVec);
287
288 if (LogicalShift)
289 return Builder.CreateLShr(LHS: Vec, RHS: ShiftVec);
290
291 return Builder.CreateAShr(LHS: Vec, RHS: ShiftVec);
292}
293
294// Attempt to simplify AVX2 per-element shift intrinsics to a generic IR shift.
295// Unlike the generic IR shifts, the intrinsics have defined behaviour for out
296// of range shift amounts (logical - set to zero, arithmetic - splat sign bit).
297static Value *simplifyX86varShift(const IntrinsicInst &II,
298 InstCombiner::BuilderTy &Builder) {
299 bool LogicalShift = false;
300 bool ShiftLeft = false;
301
302 switch (II.getIntrinsicID()) {
303 default:
304 llvm_unreachable("Unexpected intrinsic!");
305 case Intrinsic::x86_avx2_psrav_d:
306 case Intrinsic::x86_avx2_psrav_d_256:
307 case Intrinsic::x86_avx512_psrav_q_128:
308 case Intrinsic::x86_avx512_psrav_q_256:
309 case Intrinsic::x86_avx512_psrav_d_512:
310 case Intrinsic::x86_avx512_psrav_q_512:
311 case Intrinsic::x86_avx512_psrav_w_128:
312 case Intrinsic::x86_avx512_psrav_w_256:
313 case Intrinsic::x86_avx512_psrav_w_512:
314 LogicalShift = false;
315 ShiftLeft = false;
316 break;
317 case Intrinsic::x86_avx2_psrlv_d:
318 case Intrinsic::x86_avx2_psrlv_d_256:
319 case Intrinsic::x86_avx2_psrlv_q:
320 case Intrinsic::x86_avx2_psrlv_q_256:
321 case Intrinsic::x86_avx512_psrlv_d_512:
322 case Intrinsic::x86_avx512_psrlv_q_512:
323 case Intrinsic::x86_avx512_psrlv_w_128:
324 case Intrinsic::x86_avx512_psrlv_w_256:
325 case Intrinsic::x86_avx512_psrlv_w_512:
326 LogicalShift = true;
327 ShiftLeft = false;
328 break;
329 case Intrinsic::x86_avx2_psllv_d:
330 case Intrinsic::x86_avx2_psllv_d_256:
331 case Intrinsic::x86_avx2_psllv_q:
332 case Intrinsic::x86_avx2_psllv_q_256:
333 case Intrinsic::x86_avx512_psllv_d_512:
334 case Intrinsic::x86_avx512_psllv_q_512:
335 case Intrinsic::x86_avx512_psllv_w_128:
336 case Intrinsic::x86_avx512_psllv_w_256:
337 case Intrinsic::x86_avx512_psllv_w_512:
338 LogicalShift = true;
339 ShiftLeft = true;
340 break;
341 }
342 assert((LogicalShift || !ShiftLeft) && "Only logical shifts can shift left");
343
344 Value *Vec = II.getArgOperand(i: 0);
345 Value *Amt = II.getArgOperand(i: 1);
346 auto *VT = cast<FixedVectorType>(Val: II.getType());
347 Type *SVT = VT->getElementType();
348 int NumElts = VT->getNumElements();
349 int BitWidth = SVT->getIntegerBitWidth();
350
351 // If the shift amount is guaranteed to be in-range we can replace it with a
352 // generic shift.
353 KnownBits KnownAmt =
354 llvm::computeKnownBits(V: Amt, DL: II.getDataLayout());
355 if (KnownAmt.getMaxValue().ult(RHS: BitWidth)) {
356 return (LogicalShift ? (ShiftLeft ? Builder.CreateShl(LHS: Vec, RHS: Amt)
357 : Builder.CreateLShr(LHS: Vec, RHS: Amt))
358 : Builder.CreateAShr(LHS: Vec, RHS: Amt));
359 }
360
361 // Simplify if all shift amounts are constant/undef.
362 auto *CShift = dyn_cast<Constant>(Val: Amt);
363 if (!CShift)
364 return nullptr;
365
366 // Collect each element's shift amount.
367 // We also collect special cases: UNDEF = -1, OUT-OF-RANGE = BitWidth.
368 bool AnyOutOfRange = false;
369 SmallVector<int, 8> ShiftAmts;
370 for (int I = 0; I < NumElts; ++I) {
371 auto *CElt = CShift->getAggregateElement(Elt: I);
372 if (isa_and_nonnull<UndefValue>(Val: CElt)) {
373 ShiftAmts.push_back(Elt: -1);
374 continue;
375 }
376
377 auto *COp = dyn_cast_or_null<ConstantInt>(Val: CElt);
378 if (!COp)
379 return nullptr;
380
381 // Handle out of range shifts.
382 // If LogicalShift - set to BitWidth (special case).
383 // If ArithmeticShift - set to (BitWidth - 1) (sign splat).
384 APInt ShiftVal = COp->getValue();
385 if (ShiftVal.uge(RHS: BitWidth)) {
386 AnyOutOfRange = LogicalShift;
387 ShiftAmts.push_back(Elt: LogicalShift ? BitWidth : BitWidth - 1);
388 continue;
389 }
390
391 ShiftAmts.push_back(Elt: (int)ShiftVal.getZExtValue());
392 }
393
394 // If all elements out of range or UNDEF, return vector of zeros/undefs.
395 // ArithmeticShift should only hit this if they are all UNDEF.
396 auto OutOfRange = [&](int Idx) { return (Idx < 0) || (BitWidth <= Idx); };
397 if (llvm::all_of(Range&: ShiftAmts, P: OutOfRange)) {
398 SmallVector<Constant *, 8> ConstantVec;
399 for (int Idx : ShiftAmts) {
400 if (Idx < 0) {
401 ConstantVec.push_back(Elt: UndefValue::get(T: SVT));
402 } else {
403 assert(LogicalShift && "Logical shift expected");
404 ConstantVec.push_back(Elt: ConstantInt::getNullValue(Ty: SVT));
405 }
406 }
407 return ConstantVector::get(V: ConstantVec);
408 }
409
410 // We can't handle only some out of range values with generic logical shifts.
411 if (AnyOutOfRange)
412 return nullptr;
413
414 // Build the shift amount constant vector.
415 SmallVector<Constant *, 8> ShiftVecAmts;
416 for (int Idx : ShiftAmts) {
417 if (Idx < 0)
418 ShiftVecAmts.push_back(Elt: UndefValue::get(T: SVT));
419 else
420 ShiftVecAmts.push_back(Elt: ConstantInt::get(Ty: SVT, V: Idx));
421 }
422 auto ShiftVec = ConstantVector::get(V: ShiftVecAmts);
423
424 if (ShiftLeft)
425 return Builder.CreateShl(LHS: Vec, RHS: ShiftVec);
426
427 if (LogicalShift)
428 return Builder.CreateLShr(LHS: Vec, RHS: ShiftVec);
429
430 return Builder.CreateAShr(LHS: Vec, RHS: ShiftVec);
431}
432
433static Value *simplifyX86pack(IntrinsicInst &II,
434 InstCombiner::BuilderTy &Builder, bool IsSigned) {
435 Value *Arg0 = II.getArgOperand(i: 0);
436 Value *Arg1 = II.getArgOperand(i: 1);
437 Type *ResTy = II.getType();
438
439 // Fast all undef handling.
440 if (isa<UndefValue>(Val: Arg0) && isa<UndefValue>(Val: Arg1))
441 return UndefValue::get(T: ResTy);
442
443 auto *ArgTy = cast<FixedVectorType>(Val: Arg0->getType());
444 unsigned NumLanes = ResTy->getPrimitiveSizeInBits() / 128;
445 unsigned NumSrcElts = ArgTy->getNumElements();
446 assert(cast<FixedVectorType>(ResTy)->getNumElements() == (2 * NumSrcElts) &&
447 "Unexpected packing types");
448
449 unsigned NumSrcEltsPerLane = NumSrcElts / NumLanes;
450 unsigned DstScalarSizeInBits = ResTy->getScalarSizeInBits();
451 unsigned SrcScalarSizeInBits = ArgTy->getScalarSizeInBits();
452 assert(SrcScalarSizeInBits == (2 * DstScalarSizeInBits) &&
453 "Unexpected packing types");
454
455 // Constant folding.
456 if (!isa<Constant>(Val: Arg0) || !isa<Constant>(Val: Arg1))
457 return nullptr;
458
459 // Clamp Values - signed/unsigned both use signed clamp values, but they
460 // differ on the min/max values.
461 APInt MinValue, MaxValue;
462 if (IsSigned) {
463 // PACKSS: Truncate signed value with signed saturation.
464 // Source values less than dst minint are saturated to minint.
465 // Source values greater than dst maxint are saturated to maxint.
466 MinValue =
467 APInt::getSignedMinValue(numBits: DstScalarSizeInBits).sext(width: SrcScalarSizeInBits);
468 MaxValue =
469 APInt::getSignedMaxValue(numBits: DstScalarSizeInBits).sext(width: SrcScalarSizeInBits);
470 } else {
471 // PACKUS: Truncate signed value with unsigned saturation.
472 // Source values less than zero are saturated to zero.
473 // Source values greater than dst maxuint are saturated to maxuint.
474 MinValue = APInt::getZero(numBits: SrcScalarSizeInBits);
475 MaxValue = APInt::getLowBitsSet(numBits: SrcScalarSizeInBits, loBitsSet: DstScalarSizeInBits);
476 }
477
478 auto *MinC = Constant::getIntegerValue(Ty: ArgTy, V: MinValue);
479 auto *MaxC = Constant::getIntegerValue(Ty: ArgTy, V: MaxValue);
480 Arg0 = Builder.CreateSelect(C: Builder.CreateICmpSLT(LHS: Arg0, RHS: MinC), True: MinC, False: Arg0);
481 Arg1 = Builder.CreateSelect(C: Builder.CreateICmpSLT(LHS: Arg1, RHS: MinC), True: MinC, False: Arg1);
482 Arg0 = Builder.CreateSelect(C: Builder.CreateICmpSGT(LHS: Arg0, RHS: MaxC), True: MaxC, False: Arg0);
483 Arg1 = Builder.CreateSelect(C: Builder.CreateICmpSGT(LHS: Arg1, RHS: MaxC), True: MaxC, False: Arg1);
484
485 // Shuffle clamped args together at the lane level.
486 SmallVector<int, 32> PackMask;
487 for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
488 for (unsigned Elt = 0; Elt != NumSrcEltsPerLane; ++Elt)
489 PackMask.push_back(Elt: Elt + (Lane * NumSrcEltsPerLane));
490 for (unsigned Elt = 0; Elt != NumSrcEltsPerLane; ++Elt)
491 PackMask.push_back(Elt: Elt + (Lane * NumSrcEltsPerLane) + NumSrcElts);
492 }
493 auto *Shuffle = Builder.CreateShuffleVector(V1: Arg0, V2: Arg1, Mask: PackMask);
494
495 // Truncate to dst size.
496 return Builder.CreateTrunc(V: Shuffle, DestTy: ResTy);
497}
498
499static Value *simplifyX86pmulhrsw(IntrinsicInst &II,
500 InstCombiner::BuilderTy &Builder) {
501 Value *Arg0 = II.getArgOperand(i: 0);
502 Value *Arg1 = II.getArgOperand(i: 1);
503 auto *ResTy = cast<FixedVectorType>(Val: II.getType());
504 auto *ArgTy = cast<FixedVectorType>(Val: Arg0->getType());
505 assert(ArgTy == ResTy && ResTy->getScalarSizeInBits() == 16 &&
506 "Unexpected PMULH types");
507
508 // Multiply by undef -> zero (NOT undef!) as other arg could still be zero.
509 if (isa<UndefValue>(Val: Arg0) || isa<UndefValue>(Val: Arg1))
510 return ConstantAggregateZero::get(Ty: ResTy);
511
512 // Multiply by zero.
513 if (isa<ConstantAggregateZero>(Val: Arg0) || isa<ConstantAggregateZero>(Val: Arg1))
514 return ConstantAggregateZero::get(Ty: ResTy);
515
516 // Constant folding.
517 if (!isa<Constant>(Val: Arg0) || !isa<Constant>(Val: Arg1))
518 return nullptr;
519
520 // Extend to twice the width and multiply.
521 auto *ExtTy = FixedVectorType::getExtendedElementVectorType(VTy: ArgTy);
522 Value *LHS = Builder.CreateSExt(V: Arg0, DestTy: ExtTy);
523 Value *RHS = Builder.CreateSExt(V: Arg1, DestTy: ExtTy);
524 Value *Mul = Builder.CreateMul(LHS, RHS);
525
526 // PMULHRSW: truncate to vXi18 of the most significant bits, add one and
527 // extract bits[16:1].
528 auto *RndEltTy = IntegerType::get(C&: ExtTy->getContext(), NumBits: 18);
529 auto *RndTy = FixedVectorType::get(ElementType: RndEltTy, FVTy: ExtTy);
530 Mul = Builder.CreateLShr(LHS: Mul, RHS: 14);
531 Mul = Builder.CreateTrunc(V: Mul, DestTy: RndTy);
532 Mul = Builder.CreateAdd(LHS: Mul, RHS: ConstantInt::get(Ty: RndTy, V: 1));
533 Mul = Builder.CreateLShr(LHS: Mul, RHS: 1);
534 return Builder.CreateTrunc(V: Mul, DestTy: ResTy);
535}
536
537static Value *simplifyX86pmadd(IntrinsicInst &II,
538 InstCombiner::BuilderTy &Builder,
539 bool IsPMADDWD) {
540 Value *Arg0 = II.getArgOperand(i: 0);
541 Value *Arg1 = II.getArgOperand(i: 1);
542 auto *ResTy = cast<FixedVectorType>(Val: II.getType());
543 [[maybe_unused]] auto *ArgTy = cast<FixedVectorType>(Val: Arg0->getType());
544
545 unsigned NumDstElts = ResTy->getNumElements();
546 assert(ArgTy->getNumElements() == (2 * NumDstElts) &&
547 ResTy->getScalarSizeInBits() == (2 * ArgTy->getScalarSizeInBits()) &&
548 "Unexpected PMADD types");
549
550 // Multiply by undef -> zero (NOT undef!) as other arg could still be zero.
551 if (isa<UndefValue>(Val: Arg0) || isa<UndefValue>(Val: Arg1))
552 return ConstantAggregateZero::get(Ty: ResTy);
553
554 // Multiply by zero.
555 if (isa<ConstantAggregateZero>(Val: Arg0) || isa<ConstantAggregateZero>(Val: Arg1))
556 return ConstantAggregateZero::get(Ty: ResTy);
557
558 // Constant folding.
559 if (!isa<Constant>(Val: Arg0) || !isa<Constant>(Val: Arg1))
560 return nullptr;
561
562 // Split Lo/Hi elements pairs, extend and add together.
563 // PMADDWD(X,Y) =
564 // add(mul(sext(lhs[0]),sext(rhs[0])),mul(sext(lhs[1]),sext(rhs[1])))
565 // PMADDUBSW(X,Y) =
566 // sadd_sat(mul(zext(lhs[0]),sext(rhs[0])),mul(zext(lhs[1]),sext(rhs[1])))
567 SmallVector<int> LoMask, HiMask;
568 for (unsigned I = 0; I != NumDstElts; ++I) {
569 LoMask.push_back(Elt: 2 * I + 0);
570 HiMask.push_back(Elt: 2 * I + 1);
571 }
572
573 auto *LHSLo = Builder.CreateShuffleVector(V: Arg0, Mask: LoMask);
574 auto *LHSHi = Builder.CreateShuffleVector(V: Arg0, Mask: HiMask);
575 auto *RHSLo = Builder.CreateShuffleVector(V: Arg1, Mask: LoMask);
576 auto *RHSHi = Builder.CreateShuffleVector(V: Arg1, Mask: HiMask);
577
578 auto LHSCast =
579 IsPMADDWD ? Instruction::CastOps::SExt : Instruction::CastOps::ZExt;
580 LHSLo = Builder.CreateCast(Op: LHSCast, V: LHSLo, DestTy: ResTy);
581 LHSHi = Builder.CreateCast(Op: LHSCast, V: LHSHi, DestTy: ResTy);
582 RHSLo = Builder.CreateCast(Op: Instruction::CastOps::SExt, V: RHSLo, DestTy: ResTy);
583 RHSHi = Builder.CreateCast(Op: Instruction::CastOps::SExt, V: RHSHi, DestTy: ResTy);
584 Value *Lo = Builder.CreateMul(LHS: LHSLo, RHS: RHSLo);
585 Value *Hi = Builder.CreateMul(LHS: LHSHi, RHS: RHSHi);
586 return IsPMADDWD
587 ? Builder.CreateAdd(LHS: Lo, RHS: Hi)
588 : Builder.CreateIntrinsic(RetTy: ResTy, ID: Intrinsic::sadd_sat, Args: {Lo, Hi});
589}
590
591static Value *simplifyX86movmsk(const IntrinsicInst &II,
592 InstCombiner::BuilderTy &Builder) {
593 Value *Arg = II.getArgOperand(i: 0);
594 Type *ResTy = II.getType();
595
596 // movmsk(undef) -> zero as we must ensure the upper bits are zero.
597 if (isa<UndefValue>(Val: Arg))
598 return Constant::getNullValue(Ty: ResTy);
599
600 // Preserve previous behavior and give up.
601 // TODO: treat as <8 x i8>.
602 if (II.getIntrinsicID() == Intrinsic::x86_mmx_pmovmskb)
603 return nullptr;
604
605 auto *ArgTy = cast<FixedVectorType>(Val: Arg->getType());
606
607 // Expand MOVMSK to compare/bitcast/zext:
608 // e.g. PMOVMSKB(v16i8 x):
609 // %cmp = icmp slt <16 x i8> %x, zeroinitializer
610 // %int = bitcast <16 x i1> %cmp to i16
611 // %res = zext i16 %int to i32
612 unsigned NumElts = ArgTy->getNumElements();
613 Type *IntegerTy = Builder.getIntNTy(N: NumElts);
614
615 Value *Res = Builder.CreateBitCast(V: Arg, DestTy: VectorType::getInteger(VTy: ArgTy));
616 Res = Builder.CreateIsNeg(Arg: Res);
617 Res = Builder.CreateBitCast(V: Res, DestTy: IntegerTy);
618 Res = Builder.CreateZExtOrTrunc(V: Res, DestTy: ResTy);
619 return Res;
620}
621
622static Value *simplifyX86addcarry(const IntrinsicInst &II,
623 InstCombiner::BuilderTy &Builder) {
624 Value *CarryIn = II.getArgOperand(i: 0);
625 Value *Op1 = II.getArgOperand(i: 1);
626 Value *Op2 = II.getArgOperand(i: 2);
627 Type *RetTy = II.getType();
628 Type *OpTy = Op1->getType();
629 assert(RetTy->getStructElementType(0)->isIntegerTy(8) &&
630 RetTy->getStructElementType(1) == OpTy && OpTy == Op2->getType() &&
631 "Unexpected types for x86 addcarry");
632
633 // If carry-in is zero, this is just an unsigned add with overflow.
634 if (match(V: CarryIn, P: m_ZeroInt())) {
635 Value *UAdd = Builder.CreateIntrinsic(ID: Intrinsic::uadd_with_overflow, OverloadTypes: OpTy,
636 Args: {Op1, Op2});
637 // The types have to be adjusted to match the x86 call types.
638 Value *UAddResult = Builder.CreateExtractValue(Agg: UAdd, Idxs: 0);
639 Value *UAddOV = Builder.CreateZExt(V: Builder.CreateExtractValue(Agg: UAdd, Idxs: 1),
640 DestTy: Builder.getInt8Ty());
641 Value *Res = PoisonValue::get(T: RetTy);
642 Res = Builder.CreateInsertValue(Agg: Res, Val: UAddOV, Idxs: 0);
643 return Builder.CreateInsertValue(Agg: Res, Val: UAddResult, Idxs: 1);
644 }
645
646 return nullptr;
647}
648
649static Value *simplifyTernarylogic(const IntrinsicInst &II,
650 InstCombiner::BuilderTy &Builder) {
651
652 auto *ArgImm = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 3));
653 if (!ArgImm || ArgImm->getValue().uge(RHS: 256))
654 return nullptr;
655
656 Value *ArgA = II.getArgOperand(i: 0);
657 Value *ArgB = II.getArgOperand(i: 1);
658 Value *ArgC = II.getArgOperand(i: 2);
659
660 Type *Ty = II.getType();
661
662 auto Or = [&](auto Lhs, auto Rhs) -> std::pair<Value *, uint8_t> {
663 return {Builder.CreateOr(Lhs.first, Rhs.first), Lhs.second | Rhs.second};
664 };
665 auto Xor = [&](auto Lhs, auto Rhs) -> std::pair<Value *, uint8_t> {
666 return {Builder.CreateXor(Lhs.first, Rhs.first), Lhs.second ^ Rhs.second};
667 };
668 auto And = [&](auto Lhs, auto Rhs) -> std::pair<Value *, uint8_t> {
669 return {Builder.CreateAnd(Lhs.first, Rhs.first), Lhs.second & Rhs.second};
670 };
671 auto Not = [&](auto V) -> std::pair<Value *, uint8_t> {
672 return {Builder.CreateNot(V: V.first), ~V.second};
673 };
674 auto Nor = [&](auto Lhs, auto Rhs) { return Not(Or(Lhs, Rhs)); };
675 auto Xnor = [&](auto Lhs, auto Rhs) { return Not(Xor(Lhs, Rhs)); };
676 auto Nand = [&](auto Lhs, auto Rhs) { return Not(And(Lhs, Rhs)); };
677
678 bool AIsConst = match(V: ArgA, P: m_ImmConstant());
679 bool BIsConst = match(V: ArgB, P: m_ImmConstant());
680 bool CIsConst = match(V: ArgC, P: m_ImmConstant());
681
682 bool ABIsConst = AIsConst && BIsConst;
683 bool ACIsConst = AIsConst && CIsConst;
684 bool BCIsConst = BIsConst && CIsConst;
685 bool ABCIsConst = AIsConst && BIsConst && CIsConst;
686
687 // Use for verification. Its a big table. Its difficult to go from Imm ->
688 // logic ops, but easy to verify that a set of logic ops is correct. We track
689 // the logic ops through the second value in the pair. At the end it should
690 // equal Imm.
691 std::pair<Value *, uint8_t> A = {ArgA, 0xf0};
692 std::pair<Value *, uint8_t> B = {ArgB, 0xcc};
693 std::pair<Value *, uint8_t> C = {ArgC, 0xaa};
694 std::pair<Value *, uint8_t> Res = {nullptr, 0};
695
696 // Currently we only handle cases that convert directly to another instruction
697 // or cases where all the ops are constant. This is because we don't properly
698 // handle creating ternary ops in the backend, so splitting them here may
699 // cause regressions. As the backend improves, uncomment more cases.
700
701 uint8_t Imm = ArgImm->getValue().getZExtValue();
702 switch (Imm) {
703 case 0x0:
704 Res = {Constant::getNullValue(Ty), 0};
705 break;
706 case 0x1:
707 if (ABCIsConst)
708 Res = Nor(Or(A, B), C);
709 break;
710 case 0x2:
711 if (ABCIsConst)
712 Res = And(Nor(A, B), C);
713 break;
714 case 0x3:
715 if (ABIsConst)
716 Res = Nor(A, B);
717 break;
718 case 0x4:
719 if (ABCIsConst)
720 Res = And(Nor(A, C), B);
721 break;
722 case 0x5:
723 if (ACIsConst)
724 Res = Nor(A, C);
725 break;
726 case 0x6:
727 if (ABCIsConst)
728 Res = Nor(A, Xnor(B, C));
729 break;
730 case 0x7:
731 if (ABCIsConst)
732 Res = Nor(A, And(B, C));
733 break;
734 case 0x8:
735 if (ABCIsConst)
736 Res = Nor(A, Nand(B, C));
737 break;
738 case 0x9:
739 if (ABCIsConst)
740 Res = Nor(A, Xor(B, C));
741 break;
742 case 0xa:
743 if (ACIsConst)
744 Res = Nor(A, Not(C));
745 break;
746 case 0xb:
747 if (ABCIsConst)
748 Res = Nor(A, Nor(C, Not(B)));
749 break;
750 case 0xc:
751 if (ABIsConst)
752 Res = Nor(A, Not(B));
753 break;
754 case 0xd:
755 if (ABCIsConst)
756 Res = Nor(A, Nor(B, Not(C)));
757 break;
758 case 0xe:
759 if (ABCIsConst)
760 Res = Nor(A, Nor(B, C));
761 break;
762 case 0xf:
763 Res = Not(A);
764 break;
765 case 0x10:
766 if (ABCIsConst)
767 Res = And(A, Nor(B, C));
768 break;
769 case 0x11:
770 if (BCIsConst)
771 Res = Nor(B, C);
772 break;
773 case 0x12:
774 if (ABCIsConst)
775 Res = Nor(Xnor(A, C), B);
776 break;
777 case 0x13:
778 if (ABCIsConst)
779 Res = Nor(And(A, C), B);
780 break;
781 case 0x14:
782 if (ABCIsConst)
783 Res = Nor(Xnor(A, B), C);
784 break;
785 case 0x15:
786 if (ABCIsConst)
787 Res = Nor(And(A, B), C);
788 break;
789 case 0x16:
790 if (ABCIsConst)
791 Res = Xor(Xor(A, B), And(Nand(A, B), C));
792 break;
793 case 0x17:
794 if (ABCIsConst)
795 Res = Xor(Or(A, B), Or(Xnor(A, B), C));
796 break;
797 case 0x18:
798 if (ABCIsConst)
799 Res = Nor(Xnor(A, B), Xnor(A, C));
800 break;
801 case 0x19:
802 if (ABCIsConst)
803 Res = And(Nand(A, B), Xnor(B, C));
804 break;
805 case 0x1a:
806 if (ABCIsConst)
807 Res = Xor(A, Or(And(A, B), C));
808 break;
809 case 0x1b:
810 if (ABCIsConst)
811 Res = Xor(A, Or(Xnor(A, B), C));
812 break;
813 case 0x1c:
814 if (ABCIsConst)
815 Res = Xor(A, Or(And(A, C), B));
816 break;
817 case 0x1d:
818 if (ABCIsConst)
819 Res = Xor(A, Or(Xnor(A, C), B));
820 break;
821 case 0x1e:
822 if (ABCIsConst)
823 Res = Xor(A, Or(B, C));
824 break;
825 case 0x1f:
826 if (ABCIsConst)
827 Res = Nand(A, Or(B, C));
828 break;
829 case 0x20:
830 if (ABCIsConst)
831 Res = Nor(Nand(A, C), B);
832 break;
833 case 0x21:
834 if (ABCIsConst)
835 Res = Nor(Xor(A, C), B);
836 break;
837 case 0x22:
838 if (BCIsConst)
839 Res = Nor(B, Not(C));
840 break;
841 case 0x23:
842 if (ABCIsConst)
843 Res = Nor(B, Nor(C, Not(A)));
844 break;
845 case 0x24:
846 if (ABCIsConst)
847 Res = Nor(Xnor(A, B), Xor(A, C));
848 break;
849 case 0x25:
850 if (ABCIsConst)
851 Res = Xor(A, Nand(Nand(A, B), C));
852 break;
853 case 0x26:
854 if (ABCIsConst)
855 Res = And(Nand(A, B), Xor(B, C));
856 break;
857 case 0x27:
858 if (ABCIsConst)
859 Res = Xor(Or(Xnor(A, B), C), B);
860 break;
861 case 0x28:
862 if (ABCIsConst)
863 Res = And(Xor(A, B), C);
864 break;
865 case 0x29:
866 if (ABCIsConst)
867 Res = Xor(Xor(A, B), Nor(And(A, B), C));
868 break;
869 case 0x2a:
870 if (ABCIsConst)
871 Res = And(Nand(A, B), C);
872 break;
873 case 0x2b:
874 if (ABCIsConst)
875 Res = Xor(Or(Xnor(A, B), Xor(A, C)), A);
876 break;
877 case 0x2c:
878 if (ABCIsConst)
879 Res = Nor(Xnor(A, B), Nor(B, C));
880 break;
881 case 0x2d:
882 if (ABCIsConst)
883 Res = Xor(A, Or(B, Not(C)));
884 break;
885 case 0x2e:
886 if (ABCIsConst)
887 Res = Xor(A, Or(Xor(A, C), B));
888 break;
889 case 0x2f:
890 if (ABCIsConst)
891 Res = Nand(A, Or(B, Not(C)));
892 break;
893 case 0x30:
894 if (ABIsConst)
895 Res = Nor(B, Not(A));
896 break;
897 case 0x31:
898 if (ABCIsConst)
899 Res = Nor(Nor(A, Not(C)), B);
900 break;
901 case 0x32:
902 if (ABCIsConst)
903 Res = Nor(Nor(A, C), B);
904 break;
905 case 0x33:
906 Res = Not(B);
907 break;
908 case 0x34:
909 if (ABCIsConst)
910 Res = And(Xor(A, B), Nand(B, C));
911 break;
912 case 0x35:
913 if (ABCIsConst)
914 Res = Xor(B, Or(A, Xnor(B, C)));
915 break;
916 case 0x36:
917 if (ABCIsConst)
918 Res = Xor(Or(A, C), B);
919 break;
920 case 0x37:
921 if (ABCIsConst)
922 Res = Nand(Or(A, C), B);
923 break;
924 case 0x38:
925 if (ABCIsConst)
926 Res = Nor(Xnor(A, B), Nor(A, C));
927 break;
928 case 0x39:
929 if (ABCIsConst)
930 Res = Xor(Or(A, Not(C)), B);
931 break;
932 case 0x3a:
933 if (ABCIsConst)
934 Res = Xor(B, Or(A, Xor(B, C)));
935 break;
936 case 0x3b:
937 if (ABCIsConst)
938 Res = Nand(Or(A, Not(C)), B);
939 break;
940 case 0x3c:
941 Res = Xor(A, B);
942 break;
943 case 0x3d:
944 if (ABCIsConst)
945 Res = Xor(A, Or(Nor(A, C), B));
946 break;
947 case 0x3e:
948 if (ABCIsConst)
949 Res = Xor(A, Or(Nor(A, Not(C)), B));
950 break;
951 case 0x3f:
952 if (ABIsConst)
953 Res = Nand(A, B);
954 break;
955 case 0x40:
956 if (ABCIsConst)
957 Res = Nor(Nand(A, B), C);
958 break;
959 case 0x41:
960 if (ABCIsConst)
961 Res = Nor(Xor(A, B), C);
962 break;
963 case 0x42:
964 if (ABCIsConst)
965 Res = Nor(Xor(A, B), Xnor(A, C));
966 break;
967 case 0x43:
968 if (ABCIsConst)
969 Res = Xor(A, Nand(Nand(A, C), B));
970 break;
971 case 0x44:
972 if (BCIsConst)
973 Res = Nor(C, Not(B));
974 break;
975 case 0x45:
976 if (ABCIsConst)
977 Res = Nor(Nor(B, Not(A)), C);
978 break;
979 case 0x46:
980 if (ABCIsConst)
981 Res = Xor(Or(And(A, C), B), C);
982 break;
983 case 0x47:
984 if (ABCIsConst)
985 Res = Xor(Or(Xnor(A, C), B), C);
986 break;
987 case 0x48:
988 if (ABCIsConst)
989 Res = And(Xor(A, C), B);
990 break;
991 case 0x49:
992 if (ABCIsConst)
993 Res = Xor(Or(Xnor(A, B), And(A, C)), C);
994 break;
995 case 0x4a:
996 if (ABCIsConst)
997 Res = Nor(Xnor(A, C), Nor(B, C));
998 break;
999 case 0x4b:
1000 if (ABCIsConst)
1001 Res = Xor(A, Or(C, Not(B)));
1002 break;
1003 case 0x4c:
1004 if (ABCIsConst)
1005 Res = And(Nand(A, C), B);
1006 break;
1007 case 0x4d:
1008 if (ABCIsConst)
1009 Res = Xor(Or(Xor(A, B), Xnor(A, C)), A);
1010 break;
1011 case 0x4e:
1012 if (ABCIsConst)
1013 Res = Xor(A, Or(Xor(A, B), C));
1014 break;
1015 case 0x4f:
1016 if (ABCIsConst)
1017 Res = Nand(A, Nand(B, Not(C)));
1018 break;
1019 case 0x50:
1020 if (ACIsConst)
1021 Res = Nor(C, Not(A));
1022 break;
1023 case 0x51:
1024 if (ABCIsConst)
1025 Res = Nor(Nor(A, Not(B)), C);
1026 break;
1027 case 0x52:
1028 if (ABCIsConst)
1029 Res = And(Xor(A, C), Nand(B, C));
1030 break;
1031 case 0x53:
1032 if (ABCIsConst)
1033 Res = Xor(Or(Xnor(B, C), A), C);
1034 break;
1035 case 0x54:
1036 if (ABCIsConst)
1037 Res = Nor(Nor(A, B), C);
1038 break;
1039 case 0x55:
1040 Res = Not(C);
1041 break;
1042 case 0x56:
1043 if (ABCIsConst)
1044 Res = Xor(Or(A, B), C);
1045 break;
1046 case 0x57:
1047 if (ABCIsConst)
1048 Res = Nand(Or(A, B), C);
1049 break;
1050 case 0x58:
1051 if (ABCIsConst)
1052 Res = Nor(Nor(A, B), Xnor(A, C));
1053 break;
1054 case 0x59:
1055 if (ABCIsConst)
1056 Res = Xor(Or(A, Not(B)), C);
1057 break;
1058 case 0x5a:
1059 Res = Xor(A, C);
1060 break;
1061 case 0x5b:
1062 if (ABCIsConst)
1063 Res = Xor(A, Or(Nor(A, B), C));
1064 break;
1065 case 0x5c:
1066 if (ABCIsConst)
1067 Res = Xor(Or(Xor(B, C), A), C);
1068 break;
1069 case 0x5d:
1070 if (ABCIsConst)
1071 Res = Nand(Or(A, Not(B)), C);
1072 break;
1073 case 0x5e:
1074 if (ABCIsConst)
1075 Res = Xor(A, Or(Nor(A, Not(B)), C));
1076 break;
1077 case 0x5f:
1078 if (ACIsConst)
1079 Res = Nand(A, C);
1080 break;
1081 case 0x60:
1082 if (ABCIsConst)
1083 Res = And(A, Xor(B, C));
1084 break;
1085 case 0x61:
1086 if (ABCIsConst)
1087 Res = Xor(Or(Xnor(A, B), And(B, C)), C);
1088 break;
1089 case 0x62:
1090 if (ABCIsConst)
1091 Res = Nor(Nor(A, C), Xnor(B, C));
1092 break;
1093 case 0x63:
1094 if (ABCIsConst)
1095 Res = Xor(B, Or(C, Not(A)));
1096 break;
1097 case 0x64:
1098 if (ABCIsConst)
1099 Res = Nor(Nor(A, B), Xnor(B, C));
1100 break;
1101 case 0x65:
1102 if (ABCIsConst)
1103 Res = Xor(Or(B, Not(A)), C);
1104 break;
1105 case 0x66:
1106 Res = Xor(B, C);
1107 break;
1108 case 0x67:
1109 if (ABCIsConst)
1110 Res = Or(Nor(A, B), Xor(B, C));
1111 break;
1112 case 0x68:
1113 if (ABCIsConst)
1114 Res = Xor(Xor(A, B), Nor(Nor(A, B), C));
1115 break;
1116 case 0x69:
1117 if (ABCIsConst)
1118 Res = Xor(Xnor(A, B), C);
1119 break;
1120 case 0x6a:
1121 if (ABCIsConst)
1122 Res = Xor(And(A, B), C);
1123 break;
1124 case 0x6b:
1125 if (ABCIsConst)
1126 Res = Or(Nor(A, B), Xor(Xnor(A, B), C));
1127 break;
1128 case 0x6c:
1129 if (ABCIsConst)
1130 Res = Xor(And(A, C), B);
1131 break;
1132 case 0x6d:
1133 if (ABCIsConst)
1134 Res = Xor(Or(Xnor(A, B), Nor(A, C)), C);
1135 break;
1136 case 0x6e:
1137 if (ABCIsConst)
1138 Res = Or(Nor(A, Not(B)), Xor(B, C));
1139 break;
1140 case 0x6f:
1141 if (ABCIsConst)
1142 Res = Nand(A, Xnor(B, C));
1143 break;
1144 case 0x70:
1145 if (ABCIsConst)
1146 Res = And(A, Nand(B, C));
1147 break;
1148 case 0x71:
1149 if (ABCIsConst)
1150 Res = Xor(Nor(Xor(A, B), Xor(A, C)), A);
1151 break;
1152 case 0x72:
1153 if (ABCIsConst)
1154 Res = Xor(Or(Xor(A, B), C), B);
1155 break;
1156 case 0x73:
1157 if (ABCIsConst)
1158 Res = Nand(Nand(A, Not(C)), B);
1159 break;
1160 case 0x74:
1161 if (ABCIsConst)
1162 Res = Xor(Or(Xor(A, C), B), C);
1163 break;
1164 case 0x75:
1165 if (ABCIsConst)
1166 Res = Nand(Nand(A, Not(B)), C);
1167 break;
1168 case 0x76:
1169 if (ABCIsConst)
1170 Res = Xor(B, Or(Nor(B, Not(A)), C));
1171 break;
1172 case 0x77:
1173 if (BCIsConst)
1174 Res = Nand(B, C);
1175 break;
1176 case 0x78:
1177 if (ABCIsConst)
1178 Res = Xor(A, And(B, C));
1179 break;
1180 case 0x79:
1181 if (ABCIsConst)
1182 Res = Xor(Or(Xnor(A, B), Nor(B, C)), C);
1183 break;
1184 case 0x7a:
1185 if (ABCIsConst)
1186 Res = Or(Xor(A, C), Nor(B, Not(A)));
1187 break;
1188 case 0x7b:
1189 if (ABCIsConst)
1190 Res = Nand(Xnor(A, C), B);
1191 break;
1192 case 0x7c:
1193 if (ABCIsConst)
1194 Res = Or(Xor(A, B), Nor(C, Not(A)));
1195 break;
1196 case 0x7d:
1197 if (ABCIsConst)
1198 Res = Nand(Xnor(A, B), C);
1199 break;
1200 case 0x7e:
1201 if (ABCIsConst)
1202 Res = Or(Xor(A, B), Xor(A, C));
1203 break;
1204 case 0x7f:
1205 if (ABCIsConst)
1206 Res = Nand(And(A, B), C);
1207 break;
1208 case 0x80:
1209 if (ABCIsConst)
1210 Res = And(And(A, B), C);
1211 break;
1212 case 0x81:
1213 if (ABCIsConst)
1214 Res = Nor(Xor(A, B), Xor(A, C));
1215 break;
1216 case 0x82:
1217 if (ABCIsConst)
1218 Res = And(Xnor(A, B), C);
1219 break;
1220 case 0x83:
1221 if (ABCIsConst)
1222 Res = Nor(Xor(A, B), Nor(C, Not(A)));
1223 break;
1224 case 0x84:
1225 if (ABCIsConst)
1226 Res = And(Xnor(A, C), B);
1227 break;
1228 case 0x85:
1229 if (ABCIsConst)
1230 Res = Nor(Xor(A, C), Nor(B, Not(A)));
1231 break;
1232 case 0x86:
1233 if (ABCIsConst)
1234 Res = Xor(Nor(Xnor(A, B), Nor(B, C)), C);
1235 break;
1236 case 0x87:
1237 if (ABCIsConst)
1238 Res = Xor(A, Nand(B, C));
1239 break;
1240 case 0x88:
1241 Res = And(B, C);
1242 break;
1243 case 0x89:
1244 if (ABCIsConst)
1245 Res = Xor(B, Nor(Nor(B, Not(A)), C));
1246 break;
1247 case 0x8a:
1248 if (ABCIsConst)
1249 Res = And(Nand(A, Not(B)), C);
1250 break;
1251 case 0x8b:
1252 if (ABCIsConst)
1253 Res = Xor(Nor(Xor(A, C), B), C);
1254 break;
1255 case 0x8c:
1256 if (ABCIsConst)
1257 Res = And(Nand(A, Not(C)), B);
1258 break;
1259 case 0x8d:
1260 if (ABCIsConst)
1261 Res = Xor(Nor(Xor(A, B), C), B);
1262 break;
1263 case 0x8e:
1264 if (ABCIsConst)
1265 Res = Xor(Or(Xor(A, B), Xor(A, C)), A);
1266 break;
1267 case 0x8f:
1268 if (ABCIsConst)
1269 Res = Nand(A, Nand(B, C));
1270 break;
1271 case 0x90:
1272 if (ABCIsConst)
1273 Res = And(A, Xnor(B, C));
1274 break;
1275 case 0x91:
1276 if (ABCIsConst)
1277 Res = Nor(Nor(A, Not(B)), Xor(B, C));
1278 break;
1279 case 0x92:
1280 if (ABCIsConst)
1281 Res = Xor(Nor(Xnor(A, B), Nor(A, C)), C);
1282 break;
1283 case 0x93:
1284 if (ABCIsConst)
1285 Res = Xor(Nand(A, C), B);
1286 break;
1287 case 0x94:
1288 if (ABCIsConst)
1289 Res = Nor(Nor(A, B), Xor(Xnor(A, B), C));
1290 break;
1291 case 0x95:
1292 if (ABCIsConst)
1293 Res = Xor(Nand(A, B), C);
1294 break;
1295 case 0x96:
1296 if (ABCIsConst)
1297 Res = Xor(Xor(A, B), C);
1298 break;
1299 case 0x97:
1300 if (ABCIsConst)
1301 Res = Xor(Xor(A, B), Or(Nor(A, B), C));
1302 break;
1303 case 0x98:
1304 if (ABCIsConst)
1305 Res = Nor(Nor(A, B), Xor(B, C));
1306 break;
1307 case 0x99:
1308 if (BCIsConst)
1309 Res = Xnor(B, C);
1310 break;
1311 case 0x9a:
1312 if (ABCIsConst)
1313 Res = Xor(Nor(B, Not(A)), C);
1314 break;
1315 case 0x9b:
1316 if (ABCIsConst)
1317 Res = Or(Nor(A, B), Xnor(B, C));
1318 break;
1319 case 0x9c:
1320 if (ABCIsConst)
1321 Res = Xor(B, Nor(C, Not(A)));
1322 break;
1323 case 0x9d:
1324 if (ABCIsConst)
1325 Res = Or(Nor(A, C), Xnor(B, C));
1326 break;
1327 case 0x9e:
1328 if (ABCIsConst)
1329 Res = Xor(And(Xor(A, B), Nand(B, C)), C);
1330 break;
1331 case 0x9f:
1332 if (ABCIsConst)
1333 Res = Nand(A, Xor(B, C));
1334 break;
1335 case 0xa0:
1336 Res = And(A, C);
1337 break;
1338 case 0xa1:
1339 if (ABCIsConst)
1340 Res = Xor(A, Nor(Nor(A, Not(B)), C));
1341 break;
1342 case 0xa2:
1343 if (ABCIsConst)
1344 Res = And(Or(A, Not(B)), C);
1345 break;
1346 case 0xa3:
1347 if (ABCIsConst)
1348 Res = Xor(Nor(Xor(B, C), A), C);
1349 break;
1350 case 0xa4:
1351 if (ABCIsConst)
1352 Res = Xor(A, Nor(Nor(A, B), C));
1353 break;
1354 case 0xa5:
1355 if (ACIsConst)
1356 Res = Xnor(A, C);
1357 break;
1358 case 0xa6:
1359 if (ABCIsConst)
1360 Res = Xor(Nor(A, Not(B)), C);
1361 break;
1362 case 0xa7:
1363 if (ABCIsConst)
1364 Res = Or(Nor(A, B), Xnor(A, C));
1365 break;
1366 case 0xa8:
1367 if (ABCIsConst)
1368 Res = And(Or(A, B), C);
1369 break;
1370 case 0xa9:
1371 if (ABCIsConst)
1372 Res = Xor(Nor(A, B), C);
1373 break;
1374 case 0xaa:
1375 Res = std::move(C);
1376 break;
1377 case 0xab:
1378 if (ABCIsConst)
1379 Res = Or(Nor(A, B), C);
1380 break;
1381 case 0xac:
1382 if (ABCIsConst)
1383 Res = Xor(Nor(Xnor(B, C), A), C);
1384 break;
1385 case 0xad:
1386 if (ABCIsConst)
1387 Res = Or(Xnor(A, C), And(B, C));
1388 break;
1389 case 0xae:
1390 if (ABCIsConst)
1391 Res = Or(Nor(A, Not(B)), C);
1392 break;
1393 case 0xaf:
1394 if (ACIsConst)
1395 Res = Or(C, Not(A));
1396 break;
1397 case 0xb0:
1398 if (ABCIsConst)
1399 Res = And(A, Nand(B, Not(C)));
1400 break;
1401 case 0xb1:
1402 if (ABCIsConst)
1403 Res = Xor(A, Nor(Xor(A, B), C));
1404 break;
1405 case 0xb2:
1406 if (ABCIsConst)
1407 Res = Xor(Nor(Xor(A, B), Xnor(A, C)), A);
1408 break;
1409 case 0xb3:
1410 if (ABCIsConst)
1411 Res = Nand(Nand(A, C), B);
1412 break;
1413 case 0xb4:
1414 if (ABCIsConst)
1415 Res = Xor(A, Nor(C, Not(B)));
1416 break;
1417 case 0xb5:
1418 if (ABCIsConst)
1419 Res = Or(Xnor(A, C), Nor(B, C));
1420 break;
1421 case 0xb6:
1422 if (ABCIsConst)
1423 Res = Xor(And(Xor(A, B), Nand(A, C)), C);
1424 break;
1425 case 0xb7:
1426 if (ABCIsConst)
1427 Res = Nand(Xor(A, C), B);
1428 break;
1429 case 0xb8:
1430 if (ABCIsConst)
1431 Res = Xor(Nor(Xnor(A, C), B), C);
1432 break;
1433 case 0xb9:
1434 if (ABCIsConst)
1435 Res = Xor(Nor(And(A, C), B), C);
1436 break;
1437 case 0xba:
1438 if (ABCIsConst)
1439 Res = Or(Nor(B, Not(A)), C);
1440 break;
1441 case 0xbb:
1442 if (BCIsConst)
1443 Res = Or(C, Not(B));
1444 break;
1445 case 0xbc:
1446 if (ABCIsConst)
1447 Res = Xor(A, And(Nand(A, C), B));
1448 break;
1449 case 0xbd:
1450 if (ABCIsConst)
1451 Res = Or(Xor(A, B), Xnor(A, C));
1452 break;
1453 case 0xbe:
1454 if (ABCIsConst)
1455 Res = Or(Xor(A, B), C);
1456 break;
1457 case 0xbf:
1458 if (ABCIsConst)
1459 Res = Or(Nand(A, B), C);
1460 break;
1461 case 0xc0:
1462 Res = And(A, B);
1463 break;
1464 case 0xc1:
1465 if (ABCIsConst)
1466 Res = Xor(A, Nor(Nor(A, Not(C)), B));
1467 break;
1468 case 0xc2:
1469 if (ABCIsConst)
1470 Res = Xor(A, Nor(Nor(A, C), B));
1471 break;
1472 case 0xc3:
1473 if (ABIsConst)
1474 Res = Xnor(A, B);
1475 break;
1476 case 0xc4:
1477 if (ABCIsConst)
1478 Res = And(Or(A, Not(C)), B);
1479 break;
1480 case 0xc5:
1481 if (ABCIsConst)
1482 Res = Xor(B, Nor(A, Xor(B, C)));
1483 break;
1484 case 0xc6:
1485 if (ABCIsConst)
1486 Res = Xor(Nor(A, Not(C)), B);
1487 break;
1488 case 0xc7:
1489 if (ABCIsConst)
1490 Res = Or(Xnor(A, B), Nor(A, C));
1491 break;
1492 case 0xc8:
1493 if (ABCIsConst)
1494 Res = And(Or(A, C), B);
1495 break;
1496 case 0xc9:
1497 if (ABCIsConst)
1498 Res = Xor(Nor(A, C), B);
1499 break;
1500 case 0xca:
1501 if (ABCIsConst)
1502 Res = Xor(B, Nor(A, Xnor(B, C)));
1503 break;
1504 case 0xcb:
1505 if (ABCIsConst)
1506 Res = Or(Xnor(A, B), And(B, C));
1507 break;
1508 case 0xcc:
1509 Res = std::move(B);
1510 break;
1511 case 0xcd:
1512 if (ABCIsConst)
1513 Res = Or(Nor(A, C), B);
1514 break;
1515 case 0xce:
1516 if (ABCIsConst)
1517 Res = Or(Nor(A, Not(C)), B);
1518 break;
1519 case 0xcf:
1520 if (ABIsConst)
1521 Res = Or(B, Not(A));
1522 break;
1523 case 0xd0:
1524 if (ABCIsConst)
1525 Res = And(A, Or(B, Not(C)));
1526 break;
1527 case 0xd1:
1528 if (ABCIsConst)
1529 Res = Xor(A, Nor(Xor(A, C), B));
1530 break;
1531 case 0xd2:
1532 if (ABCIsConst)
1533 Res = Xor(A, Nor(B, Not(C)));
1534 break;
1535 case 0xd3:
1536 if (ABCIsConst)
1537 Res = Or(Xnor(A, B), Nor(B, C));
1538 break;
1539 case 0xd4:
1540 if (ABCIsConst)
1541 Res = Xor(Nor(Xnor(A, B), Xor(A, C)), A);
1542 break;
1543 case 0xd5:
1544 if (ABCIsConst)
1545 Res = Nand(Nand(A, B), C);
1546 break;
1547 case 0xd6:
1548 if (ABCIsConst)
1549 Res = Xor(Xor(A, B), Or(And(A, B), C));
1550 break;
1551 case 0xd7:
1552 if (ABCIsConst)
1553 Res = Nand(Xor(A, B), C);
1554 break;
1555 case 0xd8:
1556 if (ABCIsConst)
1557 Res = Xor(Nor(Xnor(A, B), C), B);
1558 break;
1559 case 0xd9:
1560 if (ABCIsConst)
1561 Res = Or(And(A, B), Xnor(B, C));
1562 break;
1563 case 0xda:
1564 if (ABCIsConst)
1565 Res = Xor(A, And(Nand(A, B), C));
1566 break;
1567 case 0xdb:
1568 if (ABCIsConst)
1569 Res = Or(Xnor(A, B), Xor(A, C));
1570 break;
1571 case 0xdc:
1572 if (ABCIsConst)
1573 Res = Or(B, Nor(C, Not(A)));
1574 break;
1575 case 0xdd:
1576 if (BCIsConst)
1577 Res = Or(B, Not(C));
1578 break;
1579 case 0xde:
1580 if (ABCIsConst)
1581 Res = Or(Xor(A, C), B);
1582 break;
1583 case 0xdf:
1584 if (ABCIsConst)
1585 Res = Or(Nand(A, C), B);
1586 break;
1587 case 0xe0:
1588 if (ABCIsConst)
1589 Res = And(A, Or(B, C));
1590 break;
1591 case 0xe1:
1592 if (ABCIsConst)
1593 Res = Xor(A, Nor(B, C));
1594 break;
1595 case 0xe2:
1596 if (ABCIsConst)
1597 Res = Xor(A, Nor(Xnor(A, C), B));
1598 break;
1599 case 0xe3:
1600 if (ABCIsConst)
1601 Res = Xor(A, Nor(And(A, C), B));
1602 break;
1603 case 0xe4:
1604 if (ABCIsConst)
1605 Res = Xor(A, Nor(Xnor(A, B), C));
1606 break;
1607 case 0xe5:
1608 if (ABCIsConst)
1609 Res = Xor(A, Nor(And(A, B), C));
1610 break;
1611 case 0xe6:
1612 if (ABCIsConst)
1613 Res = Or(And(A, B), Xor(B, C));
1614 break;
1615 case 0xe7:
1616 if (ABCIsConst)
1617 Res = Or(Xnor(A, B), Xnor(A, C));
1618 break;
1619 case 0xe8:
1620 if (ABCIsConst)
1621 Res = Xor(Or(A, B), Nor(Xnor(A, B), C));
1622 break;
1623 case 0xe9:
1624 if (ABCIsConst)
1625 Res = Xor(Xor(A, B), Nand(Nand(A, B), C));
1626 break;
1627 case 0xea:
1628 if (ABCIsConst)
1629 Res = Or(And(A, B), C);
1630 break;
1631 case 0xeb:
1632 if (ABCIsConst)
1633 Res = Or(Xnor(A, B), C);
1634 break;
1635 case 0xec:
1636 if (ABCIsConst)
1637 Res = Or(And(A, C), B);
1638 break;
1639 case 0xed:
1640 if (ABCIsConst)
1641 Res = Or(Xnor(A, C), B);
1642 break;
1643 case 0xee:
1644 Res = Or(B, C);
1645 break;
1646 case 0xef:
1647 if (ABCIsConst)
1648 Res = Nand(A, Nor(B, C));
1649 break;
1650 case 0xf0:
1651 Res = std::move(A);
1652 break;
1653 case 0xf1:
1654 if (ABCIsConst)
1655 Res = Or(A, Nor(B, C));
1656 break;
1657 case 0xf2:
1658 if (ABCIsConst)
1659 Res = Or(A, Nor(B, Not(C)));
1660 break;
1661 case 0xf3:
1662 if (ABIsConst)
1663 Res = Or(A, Not(B));
1664 break;
1665 case 0xf4:
1666 if (ABCIsConst)
1667 Res = Or(A, Nor(C, Not(B)));
1668 break;
1669 case 0xf5:
1670 if (ACIsConst)
1671 Res = Or(A, Not(C));
1672 break;
1673 case 0xf6:
1674 if (ABCIsConst)
1675 Res = Or(A, Xor(B, C));
1676 break;
1677 case 0xf7:
1678 if (ABCIsConst)
1679 Res = Or(A, Nand(B, C));
1680 break;
1681 case 0xf8:
1682 if (ABCIsConst)
1683 Res = Or(A, And(B, C));
1684 break;
1685 case 0xf9:
1686 if (ABCIsConst)
1687 Res = Or(A, Xnor(B, C));
1688 break;
1689 case 0xfa:
1690 Res = Or(A, C);
1691 break;
1692 case 0xfb:
1693 if (ABCIsConst)
1694 Res = Nand(Nor(A, C), B);
1695 break;
1696 case 0xfc:
1697 Res = Or(A, B);
1698 break;
1699 case 0xfd:
1700 if (ABCIsConst)
1701 Res = Nand(Nor(A, B), C);
1702 break;
1703 case 0xfe:
1704 if (ABCIsConst)
1705 Res = Or(Or(A, B), C);
1706 break;
1707 case 0xff:
1708 Res = {Constant::getAllOnesValue(Ty), 0xff};
1709 break;
1710 }
1711
1712 assert((Res.first == nullptr || Res.second == Imm) &&
1713 "Simplification of ternary logic does not verify!");
1714 return Res.first;
1715}
1716
1717static Value *simplifyX86FPMaxMin(const IntrinsicInst &II, InstCombiner &IC,
1718 Intrinsic::ID NewIID, bool IsScalar = false) {
1719
1720 Value *Arg0 = II.getArgOperand(i: 0);
1721 Value *Arg1 = II.getArgOperand(i: 1);
1722 unsigned VWidth = cast<FixedVectorType>(Val: Arg0->getType())->getNumElements();
1723
1724 SimplifyQuery SQ = IC.getSimplifyQuery().getWithInstruction(I: &II);
1725 APInt DemandedElts =
1726 IsScalar ? APInt::getOneBitSet(numBits: VWidth, BitNo: 0) : APInt::getAllOnes(numBits: VWidth);
1727
1728 FPClassTest Forbidden0 = fcNan | fcInf | fcSubnormal;
1729 FPClassTest Forbidden1 = fcNan | fcInf | fcSubnormal;
1730 if (NewIID == Intrinsic::maxnum) {
1731 // For maxnum, only forbid NegZero in the second operand.
1732 Forbidden1 |= fcNegZero;
1733 } else {
1734 assert(NewIID == Intrinsic::minnum && "Unknown intrinsic");
1735 // For minnum, only forbid NegZero in the first operand.
1736 Forbidden0 |= fcNegZero;
1737 }
1738 KnownFPClass KnownArg0 =
1739 computeKnownFPClass(V: Arg0, DemandedElts, InterestedClasses: Forbidden0, SQ);
1740 KnownFPClass KnownArg1 =
1741 computeKnownFPClass(V: Arg1, DemandedElts, InterestedClasses: Forbidden1, SQ);
1742
1743 if (KnownArg0.isKnownNever(Mask: Forbidden0) &&
1744 KnownArg1.isKnownNever(Mask: Forbidden1)) {
1745 if (IsScalar) {
1746 // It performs the operation on the first element and puts it back into
1747 // the vector.
1748 Value *Scalar0 = IC.Builder.CreateExtractElement(Vec: Arg0, Idx: (uint64_t)0);
1749 Value *Scalar1 = IC.Builder.CreateExtractElement(Vec: Arg1, Idx: (uint64_t)0);
1750
1751 Value *NewScalar = (NewIID == Intrinsic::maxnum)
1752 ? IC.Builder.CreateMaxNum(LHS: Scalar0, RHS: Scalar1)
1753 : IC.Builder.CreateMinNum(LHS: Scalar0, RHS: Scalar1);
1754 return IC.Builder.CreateInsertElement(Vec: Arg0, NewElt: NewScalar, Idx: (uint64_t)0);
1755 } else {
1756 return (NewIID == Intrinsic::maxnum)
1757 ? IC.Builder.CreateMaxNum(LHS: Arg0, RHS: Arg1)
1758 : IC.Builder.CreateMinNum(LHS: Arg0, RHS: Arg1);
1759 }
1760 }
1761
1762 return nullptr;
1763}
1764
1765static Value *simplifyX86insertps(const IntrinsicInst &II,
1766 InstCombiner::BuilderTy &Builder) {
1767 auto *CInt = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 2));
1768 if (!CInt)
1769 return nullptr;
1770
1771 auto *VecTy = cast<FixedVectorType>(Val: II.getType());
1772 assert(VecTy->getNumElements() == 4 && "insertps with wrong vector type");
1773
1774 // The immediate permute control byte looks like this:
1775 // [3:0] - zero mask for each 32-bit lane
1776 // [5:4] - select one 32-bit destination lane
1777 // [7:6] - select one 32-bit source lane
1778
1779 uint8_t Imm = CInt->getZExtValue();
1780 uint8_t ZMask = Imm & 0xf;
1781 uint8_t DestLane = (Imm >> 4) & 0x3;
1782 uint8_t SourceLane = (Imm >> 6) & 0x3;
1783
1784 ConstantAggregateZero *ZeroVector = ConstantAggregateZero::get(Ty: VecTy);
1785
1786 // If all zero mask bits are set, this was just a weird way to
1787 // generate a zero vector.
1788 if (ZMask == 0xf)
1789 return ZeroVector;
1790
1791 // Initialize by passing all of the first source bits through.
1792 int ShuffleMask[4] = {0, 1, 2, 3};
1793
1794 // We may replace the second operand with the zero vector.
1795 Value *V1 = II.getArgOperand(i: 1);
1796
1797 if (ZMask) {
1798 // If the zero mask is being used with a single input or the zero mask
1799 // overrides the destination lane, this is a shuffle with the zero vector.
1800 if ((II.getArgOperand(i: 0) == II.getArgOperand(i: 1)) ||
1801 (ZMask & (1 << DestLane))) {
1802 V1 = ZeroVector;
1803 // We may still move 32-bits of the first source vector from one lane
1804 // to another.
1805 ShuffleMask[DestLane] = SourceLane;
1806 // The zero mask may override the previous insert operation.
1807 for (unsigned i = 0; i < 4; ++i)
1808 if ((ZMask >> i) & 0x1)
1809 ShuffleMask[i] = i + 4;
1810 } else {
1811 // TODO: Model this case as 2 shuffles or a 'logical and' plus shuffle?
1812 return nullptr;
1813 }
1814 } else {
1815 // Replace the selected destination lane with the selected source lane.
1816 ShuffleMask[DestLane] = SourceLane + 4;
1817 }
1818
1819 return Builder.CreateShuffleVector(V1: II.getArgOperand(i: 0), V2: V1, Mask: ShuffleMask);
1820}
1821
1822/// Attempt to simplify SSE4A EXTRQ/EXTRQI instructions using constant folding
1823/// or conversion to a shuffle vector.
1824static Value *simplifyX86extrq(IntrinsicInst &II, Value *Op0,
1825 ConstantInt *CILength, ConstantInt *CIIndex,
1826 InstCombiner::BuilderTy &Builder) {
1827 auto LowConstantHighUndef = [&](uint64_t Val) {
1828 Type *IntTy64 = Type::getInt64Ty(C&: II.getContext());
1829 Constant *Args[] = {ConstantInt::get(Ty: IntTy64, V: Val),
1830 UndefValue::get(T: IntTy64)};
1831 return ConstantVector::get(V: Args);
1832 };
1833
1834 // See if we're dealing with constant values.
1835 auto *C0 = dyn_cast<Constant>(Val: Op0);
1836 auto *CI0 =
1837 C0 ? dyn_cast_or_null<ConstantInt>(Val: C0->getAggregateElement(Elt: (unsigned)0))
1838 : nullptr;
1839
1840 // Attempt to constant fold.
1841 if (CILength && CIIndex) {
1842 // From AMD documentation: "The bit index and field length are each six
1843 // bits in length other bits of the field are ignored."
1844 APInt APIndex = CIIndex->getValue().zextOrTrunc(width: 6);
1845 APInt APLength = CILength->getValue().zextOrTrunc(width: 6);
1846
1847 unsigned Index = APIndex.getZExtValue();
1848
1849 // From AMD documentation: "a value of zero in the field length is
1850 // defined as length of 64".
1851 unsigned Length = APLength == 0 ? 64 : APLength.getZExtValue();
1852
1853 // From AMD documentation: "If the sum of the bit index + length field
1854 // is greater than 64, the results are undefined".
1855 unsigned End = Index + Length;
1856
1857 // Note that both field index and field length are 8-bit quantities.
1858 // Since variables 'Index' and 'Length' are unsigned values
1859 // obtained from zero-extending field index and field length
1860 // respectively, their sum should never wrap around.
1861 if (End > 64)
1862 return UndefValue::get(T: II.getType());
1863
1864 // If we are inserting whole bytes, we can convert this to a shuffle.
1865 // Lowering can recognize EXTRQI shuffle masks.
1866 if ((Length % 8) == 0 && (Index % 8) == 0) {
1867 // Convert bit indices to byte indices.
1868 Length /= 8;
1869 Index /= 8;
1870
1871 Type *IntTy8 = Type::getInt8Ty(C&: II.getContext());
1872 auto *ShufTy = FixedVectorType::get(ElementType: IntTy8, NumElts: 16);
1873
1874 SmallVector<int, 16> ShuffleMask;
1875 for (int i = 0; i != (int)Length; ++i)
1876 ShuffleMask.push_back(Elt: i + Index);
1877 for (int i = Length; i != 8; ++i)
1878 ShuffleMask.push_back(Elt: i + 16);
1879 for (int i = 8; i != 16; ++i)
1880 ShuffleMask.push_back(Elt: -1);
1881
1882 Value *SV = Builder.CreateShuffleVector(
1883 V1: Builder.CreateBitCast(V: Op0, DestTy: ShufTy),
1884 V2: ConstantAggregateZero::get(Ty: ShufTy), Mask: ShuffleMask);
1885 return Builder.CreateBitCast(V: SV, DestTy: II.getType());
1886 }
1887
1888 // Constant Fold - shift Index'th bit to lowest position and mask off
1889 // Length bits.
1890 if (CI0) {
1891 APInt Elt = CI0->getValue();
1892 Elt.lshrInPlace(ShiftAmt: Index);
1893 Elt = Elt.zextOrTrunc(width: Length);
1894 return LowConstantHighUndef(Elt.getZExtValue());
1895 }
1896
1897 // If we were an EXTRQ call, we'll save registers if we convert to EXTRQI.
1898 if (II.getIntrinsicID() == Intrinsic::x86_sse4a_extrq) {
1899 Value *Args[] = {Op0, CILength, CIIndex};
1900 return Builder.CreateIntrinsic(ID: Intrinsic::x86_sse4a_extrqi, Args);
1901 }
1902 }
1903
1904 // Constant Fold - extraction from zero is always {zero, undef}.
1905 if (CI0 && CI0->isZero())
1906 return LowConstantHighUndef(0);
1907
1908 return nullptr;
1909}
1910
1911/// Attempt to simplify SSE4A INSERTQ/INSERTQI instructions using constant
1912/// folding or conversion to a shuffle vector.
1913static Value *simplifyX86insertq(IntrinsicInst &II, Value *Op0, Value *Op1,
1914 APInt APLength, APInt APIndex,
1915 InstCombiner::BuilderTy &Builder) {
1916 // From AMD documentation: "The bit index and field length are each six bits
1917 // in length other bits of the field are ignored."
1918 APIndex = APIndex.zextOrTrunc(width: 6);
1919 APLength = APLength.zextOrTrunc(width: 6);
1920
1921 // Attempt to constant fold.
1922 unsigned Index = APIndex.getZExtValue();
1923
1924 // From AMD documentation: "a value of zero in the field length is
1925 // defined as length of 64".
1926 unsigned Length = APLength == 0 ? 64 : APLength.getZExtValue();
1927
1928 // From AMD documentation: "If the sum of the bit index + length field
1929 // is greater than 64, the results are undefined".
1930 unsigned End = Index + Length;
1931
1932 // Note that both field index and field length are 8-bit quantities.
1933 // Since variables 'Index' and 'Length' are unsigned values
1934 // obtained from zero-extending field index and field length
1935 // respectively, their sum should never wrap around.
1936 if (End > 64)
1937 return UndefValue::get(T: II.getType());
1938
1939 // If we are inserting whole bytes, we can convert this to a shuffle.
1940 // Lowering can recognize INSERTQI shuffle masks.
1941 if ((Length % 8) == 0 && (Index % 8) == 0) {
1942 // Convert bit indices to byte indices.
1943 Length /= 8;
1944 Index /= 8;
1945
1946 Type *IntTy8 = Type::getInt8Ty(C&: II.getContext());
1947 auto *ShufTy = FixedVectorType::get(ElementType: IntTy8, NumElts: 16);
1948
1949 SmallVector<int, 16> ShuffleMask;
1950 for (int i = 0; i != (int)Index; ++i)
1951 ShuffleMask.push_back(Elt: i);
1952 for (int i = 0; i != (int)Length; ++i)
1953 ShuffleMask.push_back(Elt: i + 16);
1954 for (int i = Index + Length; i != 8; ++i)
1955 ShuffleMask.push_back(Elt: i);
1956 for (int i = 8; i != 16; ++i)
1957 ShuffleMask.push_back(Elt: -1);
1958
1959 Value *SV = Builder.CreateShuffleVector(V1: Builder.CreateBitCast(V: Op0, DestTy: ShufTy),
1960 V2: Builder.CreateBitCast(V: Op1, DestTy: ShufTy),
1961 Mask: ShuffleMask);
1962 return Builder.CreateBitCast(V: SV, DestTy: II.getType());
1963 }
1964
1965 // See if we're dealing with constant values.
1966 auto *C0 = dyn_cast<Constant>(Val: Op0);
1967 auto *C1 = dyn_cast<Constant>(Val: Op1);
1968 auto *CI00 =
1969 C0 ? dyn_cast_or_null<ConstantInt>(Val: C0->getAggregateElement(Elt: (unsigned)0))
1970 : nullptr;
1971 auto *CI10 =
1972 C1 ? dyn_cast_or_null<ConstantInt>(Val: C1->getAggregateElement(Elt: (unsigned)0))
1973 : nullptr;
1974
1975 // Constant Fold - insert bottom Length bits starting at the Index'th bit.
1976 if (CI00 && CI10) {
1977 APInt V00 = CI00->getValue();
1978 APInt V10 = CI10->getValue();
1979 APInt Mask = APInt::getLowBitsSet(numBits: 64, loBitsSet: Length).shl(shiftAmt: Index);
1980 V00 = V00 & ~Mask;
1981 V10 = V10.zextOrTrunc(width: Length).zextOrTrunc(width: 64).shl(shiftAmt: Index);
1982 APInt Val = V00 | V10;
1983 Type *IntTy64 = Type::getInt64Ty(C&: II.getContext());
1984 Constant *Args[] = {ConstantInt::get(Ty: IntTy64, V: Val.getZExtValue()),
1985 UndefValue::get(T: IntTy64)};
1986 return ConstantVector::get(V: Args);
1987 }
1988
1989 // If we were an INSERTQ call, we'll save demanded elements if we convert to
1990 // INSERTQI.
1991 if (II.getIntrinsicID() == Intrinsic::x86_sse4a_insertq) {
1992 Type *IntTy8 = Type::getInt8Ty(C&: II.getContext());
1993 Constant *CILength = ConstantInt::get(Ty: IntTy8, V: Length, IsSigned: false);
1994 Constant *CIIndex = ConstantInt::get(Ty: IntTy8, V: Index, IsSigned: false);
1995
1996 Value *Args[] = {Op0, Op1, CILength, CIIndex};
1997 return Builder.CreateIntrinsic(ID: Intrinsic::x86_sse4a_insertqi, Args);
1998 }
1999
2000 return nullptr;
2001}
2002
2003/// Attempt to convert pshufb* to shufflevector if the mask is constant.
2004static Value *simplifyX86pshufb(const IntrinsicInst &II,
2005 InstCombiner::BuilderTy &Builder) {
2006 auto *V = dyn_cast<Constant>(Val: II.getArgOperand(i: 1));
2007 if (!V)
2008 return nullptr;
2009
2010 auto *VecTy = cast<FixedVectorType>(Val: II.getType());
2011 unsigned NumElts = VecTy->getNumElements();
2012 assert((NumElts == 16 || NumElts == 32 || NumElts == 64) &&
2013 "Unexpected number of elements in shuffle mask!");
2014
2015 // Construct a shuffle mask from constant integers or UNDEFs.
2016 int Indexes[64];
2017
2018 // Each byte in the shuffle control mask forms an index to permute the
2019 // corresponding byte in the destination operand.
2020 for (unsigned I = 0; I < NumElts; ++I) {
2021 Constant *COp = V->getAggregateElement(Elt: I);
2022 if (!COp || (!isa<UndefValue>(Val: COp) && !isa<ConstantInt>(Val: COp)))
2023 return nullptr;
2024
2025 if (isa<UndefValue>(Val: COp)) {
2026 Indexes[I] = -1;
2027 continue;
2028 }
2029
2030 int8_t Index = cast<ConstantInt>(Val: COp)->getValue().getZExtValue();
2031
2032 // If the most significant bit (bit[7]) of each byte of the shuffle
2033 // control mask is set, then zero is written in the result byte.
2034 // The zero vector is in the right-hand side of the resulting
2035 // shufflevector.
2036
2037 // The value of each index for the high 128-bit lane is the least
2038 // significant 4 bits of the respective shuffle control byte.
2039 Index = ((Index < 0) ? NumElts : Index & 0x0F) + (I & 0xF0);
2040 Indexes[I] = Index;
2041 }
2042
2043 auto V1 = II.getArgOperand(i: 0);
2044 auto V2 = Constant::getNullValue(Ty: VecTy);
2045 return Builder.CreateShuffleVector(V1, V2, Mask: ArrayRef(Indexes, NumElts));
2046}
2047
2048/// Attempt to convert vpermilvar* to shufflevector if the mask is constant.
2049static Value *simplifyX86vpermilvar(const IntrinsicInst &II,
2050 InstCombiner::BuilderTy &Builder) {
2051 auto *V = dyn_cast<Constant>(Val: II.getArgOperand(i: 1));
2052 if (!V)
2053 return nullptr;
2054
2055 auto *VecTy = cast<FixedVectorType>(Val: II.getType());
2056 unsigned NumElts = VecTy->getNumElements();
2057 bool IsPD = VecTy->getScalarType()->isDoubleTy();
2058 unsigned NumLaneElts = IsPD ? 2 : 4;
2059 assert(NumElts == 16 || NumElts == 8 || NumElts == 4 || NumElts == 2);
2060
2061 // Construct a shuffle mask from constant integers or UNDEFs.
2062 int Indexes[16];
2063
2064 // The intrinsics only read one or two bits, clear the rest.
2065 for (unsigned I = 0; I < NumElts; ++I) {
2066 Constant *COp = V->getAggregateElement(Elt: I);
2067 if (!COp || (!isa<UndefValue>(Val: COp) && !isa<ConstantInt>(Val: COp)))
2068 return nullptr;
2069
2070 if (isa<UndefValue>(Val: COp)) {
2071 Indexes[I] = -1;
2072 continue;
2073 }
2074
2075 APInt Index = cast<ConstantInt>(Val: COp)->getValue();
2076 Index = Index.zextOrTrunc(width: 32).getLoBits(numBits: 2);
2077
2078 // The PD variants uses bit 1 to select per-lane element index, so
2079 // shift down to convert to generic shuffle mask index.
2080 if (IsPD)
2081 Index.lshrInPlace(ShiftAmt: 1);
2082
2083 // The _256 variants are a bit trickier since the mask bits always index
2084 // into the corresponding 128 half. In order to convert to a generic
2085 // shuffle, we have to make that explicit.
2086 Index += APInt(32, (I / NumLaneElts) * NumLaneElts);
2087
2088 Indexes[I] = Index.getZExtValue();
2089 }
2090
2091 auto V1 = II.getArgOperand(i: 0);
2092 return Builder.CreateShuffleVector(V: V1, Mask: ArrayRef(Indexes, NumElts));
2093}
2094
2095/// Attempt to convert vpermd/vpermps to shufflevector if the mask is constant.
2096static Value *simplifyX86vpermv(const IntrinsicInst &II,
2097 InstCombiner::BuilderTy &Builder) {
2098 auto *V = dyn_cast<Constant>(Val: II.getArgOperand(i: 1));
2099 if (!V)
2100 return nullptr;
2101
2102 auto *VecTy = cast<FixedVectorType>(Val: II.getType());
2103 unsigned Size = VecTy->getNumElements();
2104 assert((Size == 4 || Size == 8 || Size == 16 || Size == 32 || Size == 64) &&
2105 "Unexpected shuffle mask size");
2106
2107 // Construct a shuffle mask from constant integers or UNDEFs.
2108 int Indexes[64];
2109
2110 for (unsigned I = 0; I < Size; ++I) {
2111 Constant *COp = V->getAggregateElement(Elt: I);
2112 if (!COp || (!isa<UndefValue>(Val: COp) && !isa<ConstantInt>(Val: COp)))
2113 return nullptr;
2114
2115 if (isa<UndefValue>(Val: COp)) {
2116 Indexes[I] = -1;
2117 continue;
2118 }
2119
2120 uint32_t Index = cast<ConstantInt>(Val: COp)->getZExtValue();
2121 Index &= Size - 1;
2122 Indexes[I] = Index;
2123 }
2124
2125 auto V1 = II.getArgOperand(i: 0);
2126 return Builder.CreateShuffleVector(V: V1, Mask: ArrayRef(Indexes, Size));
2127}
2128
2129/// Attempt to convert vpermi2/vpermt2 to shufflevector if the mask is constant.
2130static Value *simplifyX86vpermv3(const IntrinsicInst &II,
2131 InstCombiner::BuilderTy &Builder) {
2132 auto *V = dyn_cast<Constant>(Val: II.getArgOperand(i: 1));
2133 if (!V)
2134 return nullptr;
2135
2136 auto *VecTy = cast<FixedVectorType>(Val: II.getType());
2137 unsigned Size = VecTy->getNumElements();
2138 assert((Size == 2 || Size == 4 || Size == 8 || Size == 16 || Size == 32 ||
2139 Size == 64) &&
2140 "Unexpected shuffle mask size");
2141
2142 // Construct a shuffle mask from constant integers or UNDEFs.
2143 int Indexes[64];
2144
2145 for (unsigned I = 0; I < Size; ++I) {
2146 Constant *COp = V->getAggregateElement(Elt: I);
2147 if (!COp || (!isa<UndefValue>(Val: COp) && !isa<ConstantInt>(Val: COp)))
2148 return nullptr;
2149
2150 if (isa<UndefValue>(Val: COp)) {
2151 Indexes[I] = -1;
2152 continue;
2153 }
2154
2155 uint32_t Index = cast<ConstantInt>(Val: COp)->getZExtValue();
2156 Index &= (2 * Size) - 1;
2157 Indexes[I] = Index;
2158 }
2159
2160 auto V1 = II.getArgOperand(i: 0);
2161 auto V2 = II.getArgOperand(i: 2);
2162 return Builder.CreateShuffleVector(V1, V2, Mask: ArrayRef(Indexes, Size));
2163}
2164
2165// Simplify VPERMV/VPERMV3 mask - only demand the active index bits.
2166static bool simplifyX86VPERMMask(Instruction *II, bool IsBinary,
2167 InstCombiner &IC) {
2168 auto *VecTy = cast<FixedVectorType>(Val: II->getType());
2169 unsigned EltSizeInBits = VecTy->getScalarSizeInBits();
2170 unsigned NumElts = VecTy->getNumElements();
2171 assert(isPowerOf2_32(NumElts) && isPowerOf2_32(EltSizeInBits) &&
2172 "Unexpected shuffle mask size");
2173
2174 unsigned IdxSizeInBits = Log2_32(Value: IsBinary ? (2 * NumElts) : NumElts);
2175 APInt DemandedMask = APInt::getLowBitsSet(numBits: EltSizeInBits, loBitsSet: IdxSizeInBits);
2176
2177 KnownBits KnownMask(EltSizeInBits);
2178 return IC.SimplifyDemandedBits(I: II, /*OpNo=*/1, DemandedMask, Known&: KnownMask);
2179}
2180
2181std::optional<Instruction *>
2182X86TTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
2183 auto SimplifyDemandedVectorEltsLow = [&IC](Value *Op, unsigned Width,
2184 unsigned DemandedWidth) {
2185 APInt UndefElts(Width, 0);
2186 APInt DemandedElts = APInt::getLowBitsSet(numBits: Width, loBitsSet: DemandedWidth);
2187 return IC.SimplifyDemandedVectorElts(V: Op, DemandedElts, UndefElts);
2188 };
2189
2190 Intrinsic::ID IID = II.getIntrinsicID();
2191 switch (IID) {
2192 case Intrinsic::x86_bmi_bextr_32:
2193 case Intrinsic::x86_bmi_bextr_64:
2194 case Intrinsic::x86_tbm_bextri_u32:
2195 case Intrinsic::x86_tbm_bextri_u64:
2196 // If the RHS is a constant we can try some simplifications.
2197 if (auto *C = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 1))) {
2198 uint64_t Shift = C->getZExtValue();
2199 uint64_t Length = (Shift >> 8) & 0xff;
2200 Shift &= 0xff;
2201 unsigned BitWidth = II.getType()->getIntegerBitWidth();
2202 // If the length is 0 or the shift is out of range, replace with zero.
2203 if (Length == 0 || Shift >= BitWidth) {
2204 return IC.replaceInstUsesWith(I&: II, V: ConstantInt::get(Ty: II.getType(), V: 0));
2205 }
2206 // If the LHS is also a constant, we can completely constant fold this.
2207 if (auto *InC = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 0))) {
2208 uint64_t Result = InC->getZExtValue() >> Shift;
2209 if (Length > BitWidth)
2210 Length = BitWidth;
2211 Result &= maskTrailingOnes<uint64_t>(N: Length);
2212 return IC.replaceInstUsesWith(I&: II,
2213 V: ConstantInt::get(Ty: II.getType(), V: Result));
2214 }
2215 // TODO should we turn this into 'and' if shift is 0? Or 'shl' if we
2216 // are only masking bits that a shift already cleared?
2217 }
2218 break;
2219
2220 case Intrinsic::x86_bmi_bzhi_32:
2221 case Intrinsic::x86_bmi_bzhi_64:
2222 // If the RHS is a constant we can try some simplifications.
2223 if (auto *C = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 1))) {
2224 uint64_t Index = C->getZExtValue() & 0xff;
2225 unsigned BitWidth = II.getType()->getIntegerBitWidth();
2226 if (Index >= BitWidth) {
2227 return IC.replaceInstUsesWith(I&: II, V: II.getArgOperand(i: 0));
2228 }
2229 if (Index == 0) {
2230 return IC.replaceInstUsesWith(I&: II, V: ConstantInt::get(Ty: II.getType(), V: 0));
2231 }
2232 // If the LHS is also a constant, we can completely constant fold this.
2233 if (auto *InC = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 0))) {
2234 uint64_t Result = InC->getZExtValue();
2235 Result &= maskTrailingOnes<uint64_t>(N: Index);
2236 return IC.replaceInstUsesWith(I&: II,
2237 V: ConstantInt::get(Ty: II.getType(), V: Result));
2238 }
2239 // TODO should we convert this to an AND if the RHS is constant?
2240 }
2241 break;
2242
2243 case Intrinsic::x86_sse_cvtss2si:
2244 case Intrinsic::x86_sse_cvtss2si64:
2245 case Intrinsic::x86_sse_cvttss2si:
2246 case Intrinsic::x86_sse_cvttss2si64:
2247 case Intrinsic::x86_sse2_cvtsd2si:
2248 case Intrinsic::x86_sse2_cvtsd2si64:
2249 case Intrinsic::x86_sse2_cvttsd2si:
2250 case Intrinsic::x86_sse2_cvttsd2si64:
2251 case Intrinsic::x86_avx512_vcvtss2si32:
2252 case Intrinsic::x86_avx512_vcvtss2si64:
2253 case Intrinsic::x86_avx512_vcvtss2usi32:
2254 case Intrinsic::x86_avx512_vcvtss2usi64:
2255 case Intrinsic::x86_avx512_vcvtsd2si32:
2256 case Intrinsic::x86_avx512_vcvtsd2si64:
2257 case Intrinsic::x86_avx512_vcvtsd2usi32:
2258 case Intrinsic::x86_avx512_vcvtsd2usi64:
2259 case Intrinsic::x86_avx512_cvttss2si:
2260 case Intrinsic::x86_avx512_cvttss2si64:
2261 case Intrinsic::x86_avx512_cvttss2usi:
2262 case Intrinsic::x86_avx512_cvttss2usi64:
2263 case Intrinsic::x86_avx512_cvttsd2si:
2264 case Intrinsic::x86_avx512_cvttsd2si64:
2265 case Intrinsic::x86_avx512_cvttsd2usi:
2266 case Intrinsic::x86_avx512_cvttsd2usi64: {
2267 // These intrinsics only demand the 0th element of their input vectors. If
2268 // we can simplify the input based on that, do so now.
2269 Value *Arg = II.getArgOperand(i: 0);
2270 unsigned VWidth = cast<FixedVectorType>(Val: Arg->getType())->getNumElements();
2271 if (Value *V = SimplifyDemandedVectorEltsLow(Arg, VWidth, 1)) {
2272 return IC.replaceOperand(I&: II, OpNum: 0, V);
2273 }
2274 break;
2275 }
2276
2277 case Intrinsic::x86_mmx_pmovmskb:
2278 case Intrinsic::x86_sse_movmsk_ps:
2279 case Intrinsic::x86_sse2_movmsk_pd:
2280 case Intrinsic::x86_sse2_pmovmskb_128:
2281 case Intrinsic::x86_avx_movmsk_pd_256:
2282 case Intrinsic::x86_avx_movmsk_ps_256:
2283 case Intrinsic::x86_avx2_pmovmskb:
2284 if (Value *V = simplifyX86movmsk(II, Builder&: IC.Builder)) {
2285 return IC.replaceInstUsesWith(I&: II, V);
2286 }
2287 break;
2288
2289 case Intrinsic::x86_sse_comieq_ss:
2290 case Intrinsic::x86_sse_comige_ss:
2291 case Intrinsic::x86_sse_comigt_ss:
2292 case Intrinsic::x86_sse_comile_ss:
2293 case Intrinsic::x86_sse_comilt_ss:
2294 case Intrinsic::x86_sse_comineq_ss:
2295 case Intrinsic::x86_sse_ucomieq_ss:
2296 case Intrinsic::x86_sse_ucomige_ss:
2297 case Intrinsic::x86_sse_ucomigt_ss:
2298 case Intrinsic::x86_sse_ucomile_ss:
2299 case Intrinsic::x86_sse_ucomilt_ss:
2300 case Intrinsic::x86_sse_ucomineq_ss:
2301 case Intrinsic::x86_sse2_comieq_sd:
2302 case Intrinsic::x86_sse2_comige_sd:
2303 case Intrinsic::x86_sse2_comigt_sd:
2304 case Intrinsic::x86_sse2_comile_sd:
2305 case Intrinsic::x86_sse2_comilt_sd:
2306 case Intrinsic::x86_sse2_comineq_sd:
2307 case Intrinsic::x86_sse2_ucomieq_sd:
2308 case Intrinsic::x86_sse2_ucomige_sd:
2309 case Intrinsic::x86_sse2_ucomigt_sd:
2310 case Intrinsic::x86_sse2_ucomile_sd:
2311 case Intrinsic::x86_sse2_ucomilt_sd:
2312 case Intrinsic::x86_sse2_ucomineq_sd:
2313 case Intrinsic::x86_avx512_vcomi_ss:
2314 case Intrinsic::x86_avx512_vcomi_sd:
2315 case Intrinsic::x86_avx512_mask_cmp_ss:
2316 case Intrinsic::x86_avx512_mask_cmp_sd: {
2317 // These intrinsics only demand the 0th element of their input vectors. If
2318 // we can simplify the input based on that, do so now.
2319 bool MadeChange = false;
2320 Value *Arg0 = II.getArgOperand(i: 0);
2321 Value *Arg1 = II.getArgOperand(i: 1);
2322 unsigned VWidth = cast<FixedVectorType>(Val: Arg0->getType())->getNumElements();
2323 if (Value *V = SimplifyDemandedVectorEltsLow(Arg0, VWidth, 1)) {
2324 IC.replaceOperand(I&: II, OpNum: 0, V);
2325 MadeChange = true;
2326 }
2327 if (Value *V = SimplifyDemandedVectorEltsLow(Arg1, VWidth, 1)) {
2328 IC.replaceOperand(I&: II, OpNum: 1, V);
2329 MadeChange = true;
2330 }
2331 if (MadeChange) {
2332 return &II;
2333 }
2334 break;
2335 }
2336
2337 case Intrinsic::x86_avx512_add_ps_512:
2338 case Intrinsic::x86_avx512_div_ps_512:
2339 case Intrinsic::x86_avx512_mul_ps_512:
2340 case Intrinsic::x86_avx512_sub_ps_512:
2341 case Intrinsic::x86_avx512_add_pd_512:
2342 case Intrinsic::x86_avx512_div_pd_512:
2343 case Intrinsic::x86_avx512_mul_pd_512:
2344 case Intrinsic::x86_avx512_sub_pd_512:
2345 // If the rounding mode is CUR_DIRECTION(4) we can turn these into regular
2346 // IR operations.
2347 if (auto *R = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 2))) {
2348 if (R->getValue() == 4) {
2349 Value *Arg0 = II.getArgOperand(i: 0);
2350 Value *Arg1 = II.getArgOperand(i: 1);
2351
2352 Value *V;
2353 switch (IID) {
2354 default:
2355 llvm_unreachable("Case stmts out of sync!");
2356 case Intrinsic::x86_avx512_add_ps_512:
2357 case Intrinsic::x86_avx512_add_pd_512:
2358 V = IC.Builder.CreateFAdd(L: Arg0, R: Arg1);
2359 break;
2360 case Intrinsic::x86_avx512_sub_ps_512:
2361 case Intrinsic::x86_avx512_sub_pd_512:
2362 V = IC.Builder.CreateFSub(L: Arg0, R: Arg1);
2363 break;
2364 case Intrinsic::x86_avx512_mul_ps_512:
2365 case Intrinsic::x86_avx512_mul_pd_512:
2366 V = IC.Builder.CreateFMul(L: Arg0, R: Arg1);
2367 break;
2368 case Intrinsic::x86_avx512_div_ps_512:
2369 case Intrinsic::x86_avx512_div_pd_512:
2370 V = IC.Builder.CreateFDiv(L: Arg0, R: Arg1);
2371 break;
2372 }
2373
2374 return IC.replaceInstUsesWith(I&: II, V);
2375 }
2376 }
2377 break;
2378
2379 case Intrinsic::x86_avx512_mask_add_ss_round:
2380 case Intrinsic::x86_avx512_mask_div_ss_round:
2381 case Intrinsic::x86_avx512_mask_mul_ss_round:
2382 case Intrinsic::x86_avx512_mask_sub_ss_round:
2383 case Intrinsic::x86_avx512_mask_add_sd_round:
2384 case Intrinsic::x86_avx512_mask_div_sd_round:
2385 case Intrinsic::x86_avx512_mask_mul_sd_round:
2386 case Intrinsic::x86_avx512_mask_sub_sd_round:
2387 // If the rounding mode is CUR_DIRECTION(4) we can turn these into regular
2388 // IR operations.
2389 if (auto *R = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 4))) {
2390 if (R->getValue() == 4) {
2391 // Extract the element as scalars.
2392 Value *Arg0 = II.getArgOperand(i: 0);
2393 Value *Arg1 = II.getArgOperand(i: 1);
2394 Value *LHS = IC.Builder.CreateExtractElement(Vec: Arg0, Idx: (uint64_t)0);
2395 Value *RHS = IC.Builder.CreateExtractElement(Vec: Arg1, Idx: (uint64_t)0);
2396
2397 Value *V;
2398 switch (IID) {
2399 default:
2400 llvm_unreachable("Case stmts out of sync!");
2401 case Intrinsic::x86_avx512_mask_add_ss_round:
2402 case Intrinsic::x86_avx512_mask_add_sd_round:
2403 V = IC.Builder.CreateFAdd(L: LHS, R: RHS);
2404 break;
2405 case Intrinsic::x86_avx512_mask_sub_ss_round:
2406 case Intrinsic::x86_avx512_mask_sub_sd_round:
2407 V = IC.Builder.CreateFSub(L: LHS, R: RHS);
2408 break;
2409 case Intrinsic::x86_avx512_mask_mul_ss_round:
2410 case Intrinsic::x86_avx512_mask_mul_sd_round:
2411 V = IC.Builder.CreateFMul(L: LHS, R: RHS);
2412 break;
2413 case Intrinsic::x86_avx512_mask_div_ss_round:
2414 case Intrinsic::x86_avx512_mask_div_sd_round:
2415 V = IC.Builder.CreateFDiv(L: LHS, R: RHS);
2416 break;
2417 }
2418
2419 // Handle the masking aspect of the intrinsic.
2420 Value *Mask = II.getArgOperand(i: 3);
2421 auto *C = dyn_cast<ConstantInt>(Val: Mask);
2422 // We don't need a select if we know the mask bit is a 1.
2423 if (!C || !C->getValue()[0]) {
2424 // Cast the mask to an i1 vector and then extract the lowest element.
2425 auto *MaskTy = FixedVectorType::get(
2426 ElementType: IC.Builder.getInt1Ty(),
2427 NumElts: cast<IntegerType>(Val: Mask->getType())->getBitWidth());
2428 Mask = IC.Builder.CreateBitCast(V: Mask, DestTy: MaskTy);
2429 Mask = IC.Builder.CreateExtractElement(Vec: Mask, Idx: (uint64_t)0);
2430 // Extract the lowest element from the passthru operand.
2431 Value *Passthru =
2432 IC.Builder.CreateExtractElement(Vec: II.getArgOperand(i: 2), Idx: (uint64_t)0);
2433 // The condition is derived from the mask, so we cannot infer branch
2434 // weights without value profile information. Thus mark it unknown.
2435 V = IC.Builder.CreateSelectWithUnknownProfile(C: Mask, True: V, False: Passthru,
2436 DEBUG_TYPE);
2437 }
2438
2439 // Insert the result back into the original argument 0.
2440 V = IC.Builder.CreateInsertElement(Vec: Arg0, NewElt: V, Idx: (uint64_t)0);
2441
2442 return IC.replaceInstUsesWith(I&: II, V);
2443 }
2444 }
2445 break;
2446
2447 // Generalize SSE/AVX FP to maxnum/minnum.
2448 case Intrinsic::x86_sse_max_ps:
2449 case Intrinsic::x86_sse2_max_pd:
2450 case Intrinsic::x86_avx_max_pd_256:
2451 case Intrinsic::x86_avx_max_ps_256:
2452 case Intrinsic::x86_avx512_max_pd_512:
2453 case Intrinsic::x86_avx512_max_ps_512:
2454 case Intrinsic::x86_avx512fp16_max_ph_128:
2455 case Intrinsic::x86_avx512fp16_max_ph_256:
2456 case Intrinsic::x86_avx512fp16_max_ph_512:
2457 if (Value *V = simplifyX86FPMaxMin(II, IC, NewIID: Intrinsic::maxnum))
2458 return IC.replaceInstUsesWith(I&: II, V);
2459 break;
2460 case Intrinsic::x86_sse_max_ss:
2461 case Intrinsic::x86_sse2_max_sd: {
2462 if (Value *V = simplifyX86FPMaxMin(II, IC, NewIID: Intrinsic::maxnum, IsScalar: true))
2463 return IC.replaceInstUsesWith(I&: II, V);
2464 break;
2465 }
2466
2467 case Intrinsic::x86_sse_min_ps:
2468 case Intrinsic::x86_sse2_min_pd:
2469 case Intrinsic::x86_avx_min_pd_256:
2470 case Intrinsic::x86_avx_min_ps_256:
2471 case Intrinsic::x86_avx512_min_pd_512:
2472 case Intrinsic::x86_avx512_min_ps_512:
2473 case Intrinsic::x86_avx512fp16_min_ph_128:
2474 case Intrinsic::x86_avx512fp16_min_ph_256:
2475 case Intrinsic::x86_avx512fp16_min_ph_512:
2476 if (Value *V = simplifyX86FPMaxMin(II, IC, NewIID: Intrinsic::minnum))
2477 return IC.replaceInstUsesWith(I&: II, V);
2478 break;
2479
2480 case Intrinsic::x86_sse_min_ss:
2481 case Intrinsic::x86_sse2_min_sd: {
2482 if (Value *V = simplifyX86FPMaxMin(II, IC, NewIID: Intrinsic::minnum, IsScalar: true))
2483 return IC.replaceInstUsesWith(I&: II, V);
2484 break;
2485 }
2486
2487 // Constant fold ashr( <A x Bi>, Ci ).
2488 // Constant fold lshr( <A x Bi>, Ci ).
2489 // Constant fold shl( <A x Bi>, Ci ).
2490 case Intrinsic::x86_sse2_psrai_d:
2491 case Intrinsic::x86_sse2_psrai_w:
2492 case Intrinsic::x86_avx2_psrai_d:
2493 case Intrinsic::x86_avx2_psrai_w:
2494 case Intrinsic::x86_avx512_psrai_q_128:
2495 case Intrinsic::x86_avx512_psrai_q_256:
2496 case Intrinsic::x86_avx512_psrai_d_512:
2497 case Intrinsic::x86_avx512_psrai_q_512:
2498 case Intrinsic::x86_avx512_psrai_w_512:
2499 case Intrinsic::x86_sse2_psrli_d:
2500 case Intrinsic::x86_sse2_psrli_q:
2501 case Intrinsic::x86_sse2_psrli_w:
2502 case Intrinsic::x86_avx2_psrli_d:
2503 case Intrinsic::x86_avx2_psrli_q:
2504 case Intrinsic::x86_avx2_psrli_w:
2505 case Intrinsic::x86_avx512_psrli_d_512:
2506 case Intrinsic::x86_avx512_psrli_q_512:
2507 case Intrinsic::x86_avx512_psrli_w_512:
2508 case Intrinsic::x86_sse2_pslli_d:
2509 case Intrinsic::x86_sse2_pslli_q:
2510 case Intrinsic::x86_sse2_pslli_w:
2511 case Intrinsic::x86_avx2_pslli_d:
2512 case Intrinsic::x86_avx2_pslli_q:
2513 case Intrinsic::x86_avx2_pslli_w:
2514 case Intrinsic::x86_avx512_pslli_d_512:
2515 case Intrinsic::x86_avx512_pslli_q_512:
2516 case Intrinsic::x86_avx512_pslli_w_512:
2517 if (Value *V = simplifyX86immShift(II, Builder&: IC.Builder)) {
2518 return IC.replaceInstUsesWith(I&: II, V);
2519 }
2520 break;
2521
2522 case Intrinsic::x86_sse2_psra_d:
2523 case Intrinsic::x86_sse2_psra_w:
2524 case Intrinsic::x86_avx2_psra_d:
2525 case Intrinsic::x86_avx2_psra_w:
2526 case Intrinsic::x86_avx512_psra_q_128:
2527 case Intrinsic::x86_avx512_psra_q_256:
2528 case Intrinsic::x86_avx512_psra_d_512:
2529 case Intrinsic::x86_avx512_psra_q_512:
2530 case Intrinsic::x86_avx512_psra_w_512:
2531 case Intrinsic::x86_sse2_psrl_d:
2532 case Intrinsic::x86_sse2_psrl_q:
2533 case Intrinsic::x86_sse2_psrl_w:
2534 case Intrinsic::x86_avx2_psrl_d:
2535 case Intrinsic::x86_avx2_psrl_q:
2536 case Intrinsic::x86_avx2_psrl_w:
2537 case Intrinsic::x86_avx512_psrl_d_512:
2538 case Intrinsic::x86_avx512_psrl_q_512:
2539 case Intrinsic::x86_avx512_psrl_w_512:
2540 case Intrinsic::x86_sse2_psll_d:
2541 case Intrinsic::x86_sse2_psll_q:
2542 case Intrinsic::x86_sse2_psll_w:
2543 case Intrinsic::x86_avx2_psll_d:
2544 case Intrinsic::x86_avx2_psll_q:
2545 case Intrinsic::x86_avx2_psll_w:
2546 case Intrinsic::x86_avx512_psll_d_512:
2547 case Intrinsic::x86_avx512_psll_q_512:
2548 case Intrinsic::x86_avx512_psll_w_512: {
2549 if (Value *V = simplifyX86immShift(II, Builder&: IC.Builder)) {
2550 return IC.replaceInstUsesWith(I&: II, V);
2551 }
2552
2553 // SSE2/AVX2 uses only the first 64-bits of the 128-bit vector
2554 // operand to compute the shift amount.
2555 Value *Arg1 = II.getArgOperand(i: 1);
2556 assert(Arg1->getType()->getPrimitiveSizeInBits() == 128 &&
2557 "Unexpected packed shift size");
2558 unsigned VWidth = cast<FixedVectorType>(Val: Arg1->getType())->getNumElements();
2559
2560 if (Value *V = SimplifyDemandedVectorEltsLow(Arg1, VWidth, VWidth / 2)) {
2561 return IC.replaceOperand(I&: II, OpNum: 1, V);
2562 }
2563 break;
2564 }
2565
2566 case Intrinsic::x86_avx2_psllv_d:
2567 case Intrinsic::x86_avx2_psllv_d_256:
2568 case Intrinsic::x86_avx2_psllv_q:
2569 case Intrinsic::x86_avx2_psllv_q_256:
2570 case Intrinsic::x86_avx512_psllv_d_512:
2571 case Intrinsic::x86_avx512_psllv_q_512:
2572 case Intrinsic::x86_avx512_psllv_w_128:
2573 case Intrinsic::x86_avx512_psllv_w_256:
2574 case Intrinsic::x86_avx512_psllv_w_512:
2575 case Intrinsic::x86_avx2_psrav_d:
2576 case Intrinsic::x86_avx2_psrav_d_256:
2577 case Intrinsic::x86_avx512_psrav_q_128:
2578 case Intrinsic::x86_avx512_psrav_q_256:
2579 case Intrinsic::x86_avx512_psrav_d_512:
2580 case Intrinsic::x86_avx512_psrav_q_512:
2581 case Intrinsic::x86_avx512_psrav_w_128:
2582 case Intrinsic::x86_avx512_psrav_w_256:
2583 case Intrinsic::x86_avx512_psrav_w_512:
2584 case Intrinsic::x86_avx2_psrlv_d:
2585 case Intrinsic::x86_avx2_psrlv_d_256:
2586 case Intrinsic::x86_avx2_psrlv_q:
2587 case Intrinsic::x86_avx2_psrlv_q_256:
2588 case Intrinsic::x86_avx512_psrlv_d_512:
2589 case Intrinsic::x86_avx512_psrlv_q_512:
2590 case Intrinsic::x86_avx512_psrlv_w_128:
2591 case Intrinsic::x86_avx512_psrlv_w_256:
2592 case Intrinsic::x86_avx512_psrlv_w_512:
2593 if (Value *V = simplifyX86varShift(II, Builder&: IC.Builder)) {
2594 return IC.replaceInstUsesWith(I&: II, V);
2595 }
2596 break;
2597
2598 case Intrinsic::x86_sse2_packssdw_128:
2599 case Intrinsic::x86_sse2_packsswb_128:
2600 case Intrinsic::x86_avx2_packssdw:
2601 case Intrinsic::x86_avx2_packsswb:
2602 case Intrinsic::x86_avx512_packssdw_512:
2603 case Intrinsic::x86_avx512_packsswb_512:
2604 if (Value *V = simplifyX86pack(II, Builder&: IC.Builder, IsSigned: true)) {
2605 return IC.replaceInstUsesWith(I&: II, V);
2606 }
2607 break;
2608
2609 case Intrinsic::x86_sse2_packuswb_128:
2610 case Intrinsic::x86_sse41_packusdw:
2611 case Intrinsic::x86_avx2_packusdw:
2612 case Intrinsic::x86_avx2_packuswb:
2613 case Intrinsic::x86_avx512_packusdw_512:
2614 case Intrinsic::x86_avx512_packuswb_512:
2615 if (Value *V = simplifyX86pack(II, Builder&: IC.Builder, IsSigned: false)) {
2616 return IC.replaceInstUsesWith(I&: II, V);
2617 }
2618 break;
2619
2620 case Intrinsic::x86_ssse3_pmul_hr_sw_128:
2621 case Intrinsic::x86_avx2_pmul_hr_sw:
2622 case Intrinsic::x86_avx512_pmul_hr_sw_512:
2623 if (Value *V = simplifyX86pmulhrsw(II, Builder&: IC.Builder)) {
2624 return IC.replaceInstUsesWith(I&: II, V);
2625 }
2626 break;
2627
2628 case Intrinsic::x86_sse2_pmadd_wd:
2629 case Intrinsic::x86_avx2_pmadd_wd:
2630 case Intrinsic::x86_avx512_pmaddw_d_512:
2631 if (Value *V = simplifyX86pmadd(II, Builder&: IC.Builder, IsPMADDWD: true)) {
2632 return IC.replaceInstUsesWith(I&: II, V);
2633 }
2634 break;
2635
2636 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
2637 case Intrinsic::x86_avx2_pmadd_ub_sw:
2638 case Intrinsic::x86_avx512_pmaddubs_w_512:
2639 if (Value *V = simplifyX86pmadd(II, Builder&: IC.Builder, IsPMADDWD: false)) {
2640 return IC.replaceInstUsesWith(I&: II, V);
2641 }
2642 break;
2643
2644 case Intrinsic::x86_pclmulqdq:
2645 case Intrinsic::x86_pclmulqdq_256:
2646 case Intrinsic::x86_pclmulqdq_512: {
2647 if (auto *C = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 2))) {
2648 unsigned Imm = C->getZExtValue();
2649
2650 bool MadeChange = false;
2651 Value *Arg0 = II.getArgOperand(i: 0);
2652 Value *Arg1 = II.getArgOperand(i: 1);
2653 unsigned VWidth =
2654 cast<FixedVectorType>(Val: Arg0->getType())->getNumElements();
2655
2656 APInt UndefElts1(VWidth, 0);
2657 APInt DemandedElts1 =
2658 APInt::getSplat(NewLen: VWidth, V: APInt(2, (Imm & 0x01) ? 2 : 1));
2659 if (Value *V =
2660 IC.SimplifyDemandedVectorElts(V: Arg0, DemandedElts: DemandedElts1, UndefElts&: UndefElts1)) {
2661 IC.replaceOperand(I&: II, OpNum: 0, V);
2662 MadeChange = true;
2663 }
2664
2665 APInt UndefElts2(VWidth, 0);
2666 APInt DemandedElts2 =
2667 APInt::getSplat(NewLen: VWidth, V: APInt(2, (Imm & 0x10) ? 2 : 1));
2668 if (Value *V =
2669 IC.SimplifyDemandedVectorElts(V: Arg1, DemandedElts: DemandedElts2, UndefElts&: UndefElts2)) {
2670 IC.replaceOperand(I&: II, OpNum: 1, V);
2671 MadeChange = true;
2672 }
2673
2674 // If either input elements are undef, the result is zero.
2675 if (DemandedElts1.isSubsetOf(RHS: UndefElts1) ||
2676 DemandedElts2.isSubsetOf(RHS: UndefElts2)) {
2677 return IC.replaceInstUsesWith(I&: II,
2678 V: ConstantAggregateZero::get(Ty: II.getType()));
2679 }
2680
2681 if (MadeChange) {
2682 return &II;
2683 }
2684 }
2685 break;
2686 }
2687
2688 case Intrinsic::x86_sse41_insertps:
2689 if (Value *V = simplifyX86insertps(II, Builder&: IC.Builder)) {
2690 return IC.replaceInstUsesWith(I&: II, V);
2691 }
2692 break;
2693
2694 case Intrinsic::x86_sse4a_extrq: {
2695 Value *Op0 = II.getArgOperand(i: 0);
2696 Value *Op1 = II.getArgOperand(i: 1);
2697 unsigned VWidth0 = cast<FixedVectorType>(Val: Op0->getType())->getNumElements();
2698 unsigned VWidth1 = cast<FixedVectorType>(Val: Op1->getType())->getNumElements();
2699 assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
2700 Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth0 == 2 &&
2701 VWidth1 == 16 && "Unexpected operand sizes");
2702
2703 // See if we're dealing with constant values.
2704 auto *C1 = dyn_cast<Constant>(Val: Op1);
2705 auto *CILength =
2706 C1 ? dyn_cast_or_null<ConstantInt>(Val: C1->getAggregateElement(Elt: (unsigned)0))
2707 : nullptr;
2708 auto *CIIndex =
2709 C1 ? dyn_cast_or_null<ConstantInt>(Val: C1->getAggregateElement(Elt: (unsigned)1))
2710 : nullptr;
2711
2712 // Attempt to simplify to a constant, shuffle vector or EXTRQI call.
2713 if (Value *V = simplifyX86extrq(II, Op0, CILength, CIIndex, Builder&: IC.Builder)) {
2714 return IC.replaceInstUsesWith(I&: II, V);
2715 }
2716
2717 // EXTRQ only uses the lowest 64-bits of the first 128-bit vector
2718 // operands and the lowest 16-bits of the second.
2719 bool MadeChange = false;
2720 if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth0, 1)) {
2721 IC.replaceOperand(I&: II, OpNum: 0, V);
2722 MadeChange = true;
2723 }
2724 if (Value *V = SimplifyDemandedVectorEltsLow(Op1, VWidth1, 2)) {
2725 IC.replaceOperand(I&: II, OpNum: 1, V);
2726 MadeChange = true;
2727 }
2728 if (MadeChange) {
2729 return &II;
2730 }
2731 break;
2732 }
2733
2734 case Intrinsic::x86_sse4a_extrqi: {
2735 // EXTRQI: Extract Length bits starting from Index. Zero pad the remaining
2736 // bits of the lower 64-bits. The upper 64-bits are undefined.
2737 Value *Op0 = II.getArgOperand(i: 0);
2738 unsigned VWidth = cast<FixedVectorType>(Val: Op0->getType())->getNumElements();
2739 assert(Op0->getType()->getPrimitiveSizeInBits() == 128 && VWidth == 2 &&
2740 "Unexpected operand size");
2741
2742 // See if we're dealing with constant values.
2743 auto *CILength = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 1));
2744 auto *CIIndex = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 2));
2745
2746 // Attempt to simplify to a constant or shuffle vector.
2747 if (Value *V = simplifyX86extrq(II, Op0, CILength, CIIndex, Builder&: IC.Builder)) {
2748 return IC.replaceInstUsesWith(I&: II, V);
2749 }
2750
2751 // EXTRQI only uses the lowest 64-bits of the first 128-bit vector
2752 // operand.
2753 if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth, 1)) {
2754 return IC.replaceOperand(I&: II, OpNum: 0, V);
2755 }
2756 break;
2757 }
2758
2759 case Intrinsic::x86_sse4a_insertq: {
2760 Value *Op0 = II.getArgOperand(i: 0);
2761 Value *Op1 = II.getArgOperand(i: 1);
2762 unsigned VWidth = cast<FixedVectorType>(Val: Op0->getType())->getNumElements();
2763 assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
2764 Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth == 2 &&
2765 cast<FixedVectorType>(Op1->getType())->getNumElements() == 2 &&
2766 "Unexpected operand size");
2767
2768 // See if we're dealing with constant values.
2769 auto *C1 = dyn_cast<Constant>(Val: Op1);
2770 auto *CI11 =
2771 C1 ? dyn_cast_or_null<ConstantInt>(Val: C1->getAggregateElement(Elt: (unsigned)1))
2772 : nullptr;
2773
2774 // Attempt to simplify to a constant, shuffle vector or INSERTQI call.
2775 if (CI11) {
2776 const APInt &V11 = CI11->getValue();
2777 APInt Len = V11.zextOrTrunc(width: 6);
2778 APInt Idx = V11.lshr(shiftAmt: 8).zextOrTrunc(width: 6);
2779 if (Value *V = simplifyX86insertq(II, Op0, Op1, APLength: Len, APIndex: Idx, Builder&: IC.Builder)) {
2780 return IC.replaceInstUsesWith(I&: II, V);
2781 }
2782 }
2783
2784 // INSERTQ only uses the lowest 64-bits of the first 128-bit vector
2785 // operand.
2786 if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth, 1)) {
2787 return IC.replaceOperand(I&: II, OpNum: 0, V);
2788 }
2789 break;
2790 }
2791
2792 case Intrinsic::x86_sse4a_insertqi: {
2793 // INSERTQI: Extract lowest Length bits from lower half of second source and
2794 // insert over first source starting at Index bit. The upper 64-bits are
2795 // undefined.
2796 Value *Op0 = II.getArgOperand(i: 0);
2797 Value *Op1 = II.getArgOperand(i: 1);
2798 unsigned VWidth0 = cast<FixedVectorType>(Val: Op0->getType())->getNumElements();
2799 unsigned VWidth1 = cast<FixedVectorType>(Val: Op1->getType())->getNumElements();
2800 assert(Op0->getType()->getPrimitiveSizeInBits() == 128 &&
2801 Op1->getType()->getPrimitiveSizeInBits() == 128 && VWidth0 == 2 &&
2802 VWidth1 == 2 && "Unexpected operand sizes");
2803
2804 // See if we're dealing with constant values.
2805 auto *CILength = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 2));
2806 auto *CIIndex = dyn_cast<ConstantInt>(Val: II.getArgOperand(i: 3));
2807
2808 // Attempt to simplify to a constant or shuffle vector.
2809 if (CILength && CIIndex) {
2810 APInt Len = CILength->getValue().zextOrTrunc(width: 6);
2811 APInt Idx = CIIndex->getValue().zextOrTrunc(width: 6);
2812 if (Value *V = simplifyX86insertq(II, Op0, Op1, APLength: Len, APIndex: Idx, Builder&: IC.Builder)) {
2813 return IC.replaceInstUsesWith(I&: II, V);
2814 }
2815 }
2816
2817 // INSERTQI only uses the lowest 64-bits of the first two 128-bit vector
2818 // operands.
2819 bool MadeChange = false;
2820 if (Value *V = SimplifyDemandedVectorEltsLow(Op0, VWidth0, 1)) {
2821 IC.replaceOperand(I&: II, OpNum: 0, V);
2822 MadeChange = true;
2823 }
2824 if (Value *V = SimplifyDemandedVectorEltsLow(Op1, VWidth1, 1)) {
2825 IC.replaceOperand(I&: II, OpNum: 1, V);
2826 MadeChange = true;
2827 }
2828 if (MadeChange) {
2829 return &II;
2830 }
2831 break;
2832 }
2833
2834 case Intrinsic::x86_sse41_pblendvb:
2835 case Intrinsic::x86_sse41_blendvps:
2836 case Intrinsic::x86_sse41_blendvpd:
2837 case Intrinsic::x86_avx_blendv_ps_256:
2838 case Intrinsic::x86_avx_blendv_pd_256:
2839 case Intrinsic::x86_avx2_pblendvb: {
2840 // fold (blend A, A, Mask) -> A
2841 auto *OpTy = cast<FixedVectorType>(Val: II.getType());
2842 Value *Op0 = II.getArgOperand(i: 0);
2843 Value *Op1 = II.getArgOperand(i: 1);
2844 Value *Mask = II.getArgOperand(i: 2);
2845 if (Op0 == Op1) {
2846 return IC.replaceInstUsesWith(I&: II, V: Op0);
2847 }
2848
2849 // Zero Mask - select 1st argument.
2850 if (isa<ConstantAggregateZero>(Val: Mask)) {
2851 return IC.replaceInstUsesWith(I&: II, V: Op0);
2852 }
2853
2854 // Constant Mask - select 1st/2nd argument lane based on top bit of mask.
2855 if (isa<ConstantInt, ConstantFP, ConstantDataVector>(Val: Mask)) {
2856 Constant *NewSelector =
2857 getNegativeIsTrueBoolVec(V: cast<Constant>(Val: Mask), DL: IC.getDataLayout());
2858 return SelectInst::Create(C: NewSelector, S1: Op1, S2: Op0, NameStr: "blendv");
2859 }
2860 unsigned BitWidth = Mask->getType()->getScalarSizeInBits();
2861
2862 if (Mask->getType()->isIntOrIntVectorTy()) {
2863 KnownBits Known(BitWidth);
2864 if (IC.SimplifyDemandedBits(I: &II, OpNo: 2, DemandedMask: APInt::getSignMask(BitWidth), Known))
2865 return &II;
2866 } else if (auto *BC = dyn_cast<BitCastInst>(Val: Mask)) {
2867 if (BC->hasOneUse()) {
2868 Value *Src = BC->getOperand(i_nocapture: 0);
2869 if (Src->getType()->isIntOrIntVectorTy()) {
2870 unsigned SrcBitWidth = Src->getType()->getScalarSizeInBits();
2871 if (SrcBitWidth == BitWidth) {
2872 KnownBits KnownSrc(SrcBitWidth);
2873 if (IC.SimplifyDemandedBits(I: BC, OpNo: 0, DemandedMask: APInt::getSignMask(BitWidth: SrcBitWidth),
2874 Known&: KnownSrc))
2875 return &II;
2876 }
2877 }
2878 }
2879 }
2880 Mask = InstCombiner::peekThroughBitcast(V: Mask);
2881
2882 // Bitshift upto the signbit can always be converted to an efficient
2883 // test+select pattern.
2884 if (match(V: Mask, P: m_Shl(L: m_Value(), R: m_Value()))) {
2885 if (auto *MaskTy = dyn_cast<FixedVectorType>(Val: Mask->getType())) {
2886 if (MaskTy->getScalarSizeInBits() == OpTy->getScalarSizeInBits()) {
2887 Value *BoolVec = IC.Builder.CreateICmpSGT(
2888 LHS: ConstantAggregateZero::get(Ty: MaskTy), RHS: Mask);
2889 Value *Sel = IC.Builder.CreateSelect(C: BoolVec, True: Op1, False: Op0);
2890 return new BitCastInst(Sel, II.getType());
2891 }
2892 }
2893 }
2894
2895 // Peek through a one-use shuffle - VectorCombine should have simplified
2896 // this for cases where we're splitting wider vectors to use blendv
2897 // intrinsics.
2898 Value *MaskSrc = nullptr;
2899 ArrayRef<int> ShuffleMask;
2900 if (match(V: Mask, P: m_OneUse(SubPattern: m_Shuffle(v1: m_Value(V&: MaskSrc), v2: m_Undef(),
2901 mask: m_Mask(ShuffleMask))))) {
2902 // Bail if the shuffle was irregular or contains undefs.
2903 int NumElts = cast<FixedVectorType>(Val: MaskSrc->getType())->getNumElements();
2904 if (NumElts < (int)ShuffleMask.size() || !isPowerOf2_32(Value: NumElts) ||
2905 any_of(Range&: ShuffleMask,
2906 P: [NumElts](int M) { return M < 0 || M >= NumElts; }))
2907 break;
2908 Mask = InstCombiner::peekThroughBitcast(V: MaskSrc);
2909 }
2910
2911 // Convert to a vector select if we can bypass casts and find a boolean
2912 // vector condition value.
2913 Value *BoolVec;
2914 if (match(V: Mask, P: m_SExt(Op: m_Value(V&: BoolVec))) &&
2915 BoolVec->getType()->isVectorTy() &&
2916 BoolVec->getType()->getScalarSizeInBits() == 1) {
2917 auto *MaskTy = cast<FixedVectorType>(Val: Mask->getType());
2918 unsigned NumMaskElts = MaskTy->getNumElements();
2919 unsigned NumOperandElts = OpTy->getNumElements();
2920
2921 // If we peeked through a shuffle, reapply the shuffle to the bool vector.
2922 if (MaskSrc) {
2923 unsigned NumMaskSrcElts =
2924 cast<FixedVectorType>(Val: MaskSrc->getType())->getNumElements();
2925 NumMaskElts = (ShuffleMask.size() * NumMaskElts) / NumMaskSrcElts;
2926 // Multiple mask bits maps to the same operand element - bail out.
2927 if (NumMaskElts > NumOperandElts)
2928 break;
2929 SmallVector<int> ScaledMask;
2930 if (!llvm::scaleShuffleMaskElts(NumDstElts: NumMaskElts, Mask: ShuffleMask, ScaledMask))
2931 break;
2932 BoolVec = IC.Builder.CreateShuffleVector(V: BoolVec, Mask: ScaledMask);
2933 MaskTy = FixedVectorType::get(ElementType: MaskTy->getElementType(), NumElts: NumMaskElts);
2934 }
2935 assert(MaskTy->getPrimitiveSizeInBits() ==
2936 OpTy->getPrimitiveSizeInBits() &&
2937 "Not expecting mask and operands with different sizes");
2938
2939 if (NumMaskElts == NumOperandElts) {
2940 return SelectInst::Create(C: BoolVec, S1: Op1, S2: Op0);
2941 }
2942
2943 // If the mask has less elements than the operands, each mask bit maps to
2944 // multiple elements of the operands. Bitcast back and forth.
2945 if (NumMaskElts < NumOperandElts) {
2946 Value *CastOp0 = IC.Builder.CreateBitCast(V: Op0, DestTy: MaskTy);
2947 Value *CastOp1 = IC.Builder.CreateBitCast(V: Op1, DestTy: MaskTy);
2948 Value *Sel = IC.Builder.CreateSelect(C: BoolVec, True: CastOp1, False: CastOp0);
2949 return new BitCastInst(Sel, II.getType());
2950 }
2951 }
2952
2953 break;
2954 }
2955
2956 case Intrinsic::x86_ssse3_pshuf_b_128:
2957 case Intrinsic::x86_avx2_pshuf_b:
2958 case Intrinsic::x86_avx512_pshuf_b_512: {
2959 if (Value *V = simplifyX86pshufb(II, Builder&: IC.Builder)) {
2960 return IC.replaceInstUsesWith(I&: II, V);
2961 }
2962
2963 KnownBits KnownMask(8);
2964 if (IC.SimplifyDemandedBits(I: &II, OpNo: 1, DemandedMask: APInt(8, 0b10001111), Known&: KnownMask))
2965 return &II;
2966 break;
2967 }
2968
2969 case Intrinsic::x86_avx_vpermilvar_ps:
2970 case Intrinsic::x86_avx_vpermilvar_ps_256:
2971 case Intrinsic::x86_avx512_vpermilvar_ps_512: {
2972 if (Value *V = simplifyX86vpermilvar(II, Builder&: IC.Builder)) {
2973 return IC.replaceInstUsesWith(I&: II, V);
2974 }
2975
2976 KnownBits KnownMask(32);
2977 if (IC.SimplifyDemandedBits(I: &II, OpNo: 1, DemandedMask: APInt(32, 0b00011), Known&: KnownMask))
2978 return &II;
2979 break;
2980 }
2981
2982 case Intrinsic::x86_avx_vpermilvar_pd:
2983 case Intrinsic::x86_avx_vpermilvar_pd_256:
2984 case Intrinsic::x86_avx512_vpermilvar_pd_512: {
2985 if (Value *V = simplifyX86vpermilvar(II, Builder&: IC.Builder)) {
2986 return IC.replaceInstUsesWith(I&: II, V);
2987 }
2988
2989 KnownBits KnownMask(64);
2990 if (IC.SimplifyDemandedBits(I: &II, OpNo: 1, DemandedMask: APInt(64, 0b00010), Known&: KnownMask))
2991 return &II;
2992 break;
2993 }
2994
2995 case Intrinsic::x86_avx2_permd:
2996 case Intrinsic::x86_avx2_permps:
2997 case Intrinsic::x86_avx512_permvar_df_256:
2998 case Intrinsic::x86_avx512_permvar_df_512:
2999 case Intrinsic::x86_avx512_permvar_di_256:
3000 case Intrinsic::x86_avx512_permvar_di_512:
3001 case Intrinsic::x86_avx512_permvar_hi_128:
3002 case Intrinsic::x86_avx512_permvar_hi_256:
3003 case Intrinsic::x86_avx512_permvar_hi_512:
3004 case Intrinsic::x86_avx512_permvar_qi_128:
3005 case Intrinsic::x86_avx512_permvar_qi_256:
3006 case Intrinsic::x86_avx512_permvar_qi_512:
3007 case Intrinsic::x86_avx512_permvar_sf_512:
3008 case Intrinsic::x86_avx512_permvar_si_512:
3009 if (Value *V = simplifyX86vpermv(II, Builder&: IC.Builder)) {
3010 return IC.replaceInstUsesWith(I&: II, V);
3011 }
3012 if (simplifyX86VPERMMask(II: &II, /*IsBinary=*/false, IC))
3013 return &II;
3014 break;
3015
3016 case Intrinsic::x86_avx512_vpermi2var_d_128:
3017 case Intrinsic::x86_avx512_vpermi2var_d_256:
3018 case Intrinsic::x86_avx512_vpermi2var_d_512:
3019 case Intrinsic::x86_avx512_vpermi2var_hi_128:
3020 case Intrinsic::x86_avx512_vpermi2var_hi_256:
3021 case Intrinsic::x86_avx512_vpermi2var_hi_512:
3022 case Intrinsic::x86_avx512_vpermi2var_pd_128:
3023 case Intrinsic::x86_avx512_vpermi2var_pd_256:
3024 case Intrinsic::x86_avx512_vpermi2var_pd_512:
3025 case Intrinsic::x86_avx512_vpermi2var_ps_128:
3026 case Intrinsic::x86_avx512_vpermi2var_ps_256:
3027 case Intrinsic::x86_avx512_vpermi2var_ps_512:
3028 case Intrinsic::x86_avx512_vpermi2var_q_128:
3029 case Intrinsic::x86_avx512_vpermi2var_q_256:
3030 case Intrinsic::x86_avx512_vpermi2var_q_512:
3031 case Intrinsic::x86_avx512_vpermi2var_qi_128:
3032 case Intrinsic::x86_avx512_vpermi2var_qi_256:
3033 case Intrinsic::x86_avx512_vpermi2var_qi_512:
3034 if (Value *V = simplifyX86vpermv3(II, Builder&: IC.Builder)) {
3035 return IC.replaceInstUsesWith(I&: II, V);
3036 }
3037 if (simplifyX86VPERMMask(II: &II, /*IsBinary=*/true, IC))
3038 return &II;
3039 break;
3040
3041 case Intrinsic::x86_avx_maskload_ps:
3042 case Intrinsic::x86_avx_maskload_pd:
3043 case Intrinsic::x86_avx_maskload_ps_256:
3044 case Intrinsic::x86_avx_maskload_pd_256:
3045 case Intrinsic::x86_avx2_maskload_d:
3046 case Intrinsic::x86_avx2_maskload_q:
3047 case Intrinsic::x86_avx2_maskload_d_256:
3048 case Intrinsic::x86_avx2_maskload_q_256:
3049 if (Instruction *I = simplifyX86MaskedLoad(II, IC)) {
3050 return I;
3051 }
3052 break;
3053
3054 case Intrinsic::x86_sse2_maskmov_dqu:
3055 case Intrinsic::x86_avx_maskstore_ps:
3056 case Intrinsic::x86_avx_maskstore_pd:
3057 case Intrinsic::x86_avx_maskstore_ps_256:
3058 case Intrinsic::x86_avx_maskstore_pd_256:
3059 case Intrinsic::x86_avx2_maskstore_d:
3060 case Intrinsic::x86_avx2_maskstore_q:
3061 case Intrinsic::x86_avx2_maskstore_d_256:
3062 case Intrinsic::x86_avx2_maskstore_q_256:
3063 if (simplifyX86MaskedStore(II, IC)) {
3064 return nullptr;
3065 }
3066 break;
3067
3068 case Intrinsic::x86_addcarry_32:
3069 case Intrinsic::x86_addcarry_64:
3070 if (Value *V = simplifyX86addcarry(II, Builder&: IC.Builder)) {
3071 return IC.replaceInstUsesWith(I&: II, V);
3072 }
3073 break;
3074
3075 case Intrinsic::x86_avx512_pternlog_d_128:
3076 case Intrinsic::x86_avx512_pternlog_d_256:
3077 case Intrinsic::x86_avx512_pternlog_d_512:
3078 case Intrinsic::x86_avx512_pternlog_q_128:
3079 case Intrinsic::x86_avx512_pternlog_q_256:
3080 case Intrinsic::x86_avx512_pternlog_q_512:
3081 if (Value *V = simplifyTernarylogic(II, Builder&: IC.Builder)) {
3082 return IC.replaceInstUsesWith(I&: II, V);
3083 }
3084 break;
3085
3086 case Intrinsic::x86_avx512_vpmadd52h_uq_128:
3087 case Intrinsic::x86_avx512_vpmadd52l_uq_128:
3088 case Intrinsic::x86_avx512_vpmadd52h_uq_256:
3089 case Intrinsic::x86_avx512_vpmadd52l_uq_256:
3090 case Intrinsic::x86_avx512_vpmadd52h_uq_512:
3091 case Intrinsic::x86_avx512_vpmadd52l_uq_512: {
3092 // Fold add(vpmadd52(<zero>, a, b), x) -> vpmadd52(x, a, b)
3093 Value *Acc = II.getArgOperand(i: 0);
3094 if (!match(V: Acc, P: m_Zero()) || !II.hasOneUse())
3095 break;
3096
3097 auto *Add = dyn_cast<BinaryOperator>(Val: *II.user_begin());
3098 Value *X;
3099 if (!Add || !match(V: Add, P: m_c_Add(L: m_Specific(V: &II), R: m_Value(V&: X))))
3100 break;
3101
3102 IC.Builder.SetInsertPoint(Add);
3103 Value *NewCall = IC.Builder.CreateIntrinsic(
3104 ID: IID, OverloadTypes: {}, Args: {X, II.getArgOperand(i: 1), II.getArgOperand(i: 2)});
3105
3106 IC.replaceInstUsesWith(I&: *Add, V: NewCall);
3107 IC.eraseInstFromFunction(I&: *Add);
3108 return IC.eraseInstFromFunction(I&: II);
3109 }
3110
3111 default:
3112 break;
3113 }
3114 return std::nullopt;
3115}
3116
3117std::optional<Value *> X86TTIImpl::simplifyDemandedUseBitsIntrinsic(
3118 InstCombiner &IC, IntrinsicInst &II, APInt DemandedMask, KnownBits &Known,
3119 bool &KnownBitsComputed) const {
3120 switch (II.getIntrinsicID()) {
3121 default:
3122 break;
3123 case Intrinsic::x86_mmx_pmovmskb:
3124 case Intrinsic::x86_sse_movmsk_ps:
3125 case Intrinsic::x86_sse2_movmsk_pd:
3126 case Intrinsic::x86_sse2_pmovmskb_128:
3127 case Intrinsic::x86_avx_movmsk_ps_256:
3128 case Intrinsic::x86_avx_movmsk_pd_256:
3129 case Intrinsic::x86_avx2_pmovmskb: {
3130 // MOVMSK copies the vector elements' sign bits to the low bits
3131 // and zeros the high bits.
3132 unsigned ArgWidth;
3133 if (II.getIntrinsicID() == Intrinsic::x86_mmx_pmovmskb) {
3134 ArgWidth = 8; // Arg is x86_mmx, but treated as <8 x i8>.
3135 } else {
3136 auto *ArgType = cast<FixedVectorType>(Val: II.getArgOperand(i: 0)->getType());
3137 ArgWidth = ArgType->getNumElements();
3138 }
3139
3140 // If we don't need any of low bits then return zero,
3141 // we know that DemandedMask is non-zero already.
3142 APInt DemandedElts = DemandedMask.zextOrTrunc(width: ArgWidth);
3143 Type *VTy = II.getType();
3144 if (DemandedElts.isZero()) {
3145 return ConstantInt::getNullValue(Ty: VTy);
3146 }
3147
3148 // We know that the upper bits are set to zero.
3149 Known.Zero.setBitsFrom(ArgWidth);
3150 KnownBitsComputed = true;
3151 break;
3152 }
3153 }
3154 return std::nullopt;
3155}
3156
3157std::optional<Value *> X86TTIImpl::simplifyDemandedVectorEltsIntrinsic(
3158 InstCombiner &IC, IntrinsicInst &II, APInt DemandedElts, APInt &UndefElts,
3159 APInt &UndefElts2, APInt &UndefElts3,
3160 std::function<void(Instruction *, unsigned, APInt, APInt &)>
3161 simplifyAndSetOp) const {
3162 unsigned VWidth = cast<FixedVectorType>(Val: II.getType())->getNumElements();
3163 switch (II.getIntrinsicID()) {
3164 default:
3165 break;
3166 case Intrinsic::x86_xop_vfrcz_ss:
3167 case Intrinsic::x86_xop_vfrcz_sd:
3168 // The instructions for these intrinsics are speced to zero upper bits not
3169 // pass them through like other scalar intrinsics. So we shouldn't just
3170 // use Arg0 if DemandedElts[0] is clear like we do for other intrinsics.
3171 // Instead we should return a zero vector.
3172 if (!DemandedElts[0]) {
3173 IC.addToWorklist(I: &II);
3174 return ConstantAggregateZero::get(Ty: II.getType());
3175 }
3176
3177 // Only the lower element is used.
3178 DemandedElts = 1;
3179 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3180
3181 // Only the lower element is undefined. The high elements are zero.
3182 UndefElts = UndefElts[0];
3183 break;
3184
3185 // Unary scalar-as-vector operations that work column-wise.
3186 case Intrinsic::x86_sse_rcp_ss:
3187 case Intrinsic::x86_sse_rsqrt_ss:
3188 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3189
3190 // If lowest element of a scalar op isn't used then use Arg0.
3191 if (!DemandedElts[0]) {
3192 IC.addToWorklist(I: &II);
3193 return II.getArgOperand(i: 0);
3194 }
3195 // TODO: If only low elt lower SQRT to FSQRT (with rounding/exceptions
3196 // checks).
3197 break;
3198
3199 // Binary scalar-as-vector operations that work column-wise. The high
3200 // elements come from operand 0. The low element is a function of both
3201 // operands.
3202 case Intrinsic::x86_sse_min_ss:
3203 case Intrinsic::x86_sse_max_ss:
3204 case Intrinsic::x86_sse_cmp_ss:
3205 case Intrinsic::x86_sse2_min_sd:
3206 case Intrinsic::x86_sse2_max_sd:
3207 case Intrinsic::x86_sse2_cmp_sd: {
3208 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3209
3210 // If lowest element of a scalar op isn't used then use Arg0.
3211 if (!DemandedElts[0]) {
3212 IC.addToWorklist(I: &II);
3213 return II.getArgOperand(i: 0);
3214 }
3215
3216 // Only lower element is used for operand 1.
3217 DemandedElts = 1;
3218 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
3219
3220 // Lower element is undefined if both lower elements are undefined.
3221 // Consider things like undef&0. The result is known zero, not undef.
3222 if (!UndefElts2[0])
3223 UndefElts.clearBit(BitPosition: 0);
3224
3225 break;
3226 }
3227
3228 // Binary scalar-as-vector operations that work column-wise. The high
3229 // elements come from operand 0 and the low element comes from operand 1.
3230 case Intrinsic::x86_sse41_round_ss:
3231 case Intrinsic::x86_sse41_round_sd: {
3232 // Don't use the low element of operand 0.
3233 APInt DemandedElts2 = DemandedElts;
3234 DemandedElts2.clearBit(BitPosition: 0);
3235 simplifyAndSetOp(&II, 0, DemandedElts2, UndefElts);
3236
3237 // If lowest element of a scalar op isn't used then use Arg0.
3238 if (!DemandedElts[0]) {
3239 IC.addToWorklist(I: &II);
3240 return II.getArgOperand(i: 0);
3241 }
3242
3243 // Only lower element is used for operand 1.
3244 DemandedElts = 1;
3245 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
3246
3247 // Take the high undef elements from operand 0 and take the lower element
3248 // from operand 1.
3249 UndefElts.clearBit(BitPosition: 0);
3250 UndefElts |= UndefElts2[0];
3251 break;
3252 }
3253
3254 // Three input scalar-as-vector operations that work column-wise. The high
3255 // elements come from operand 0 and the low element is a function of all
3256 // three inputs.
3257 case Intrinsic::x86_avx512_mask_add_ss_round:
3258 case Intrinsic::x86_avx512_mask_div_ss_round:
3259 case Intrinsic::x86_avx512_mask_mul_ss_round:
3260 case Intrinsic::x86_avx512_mask_sub_ss_round:
3261 case Intrinsic::x86_avx512_mask_max_ss_round:
3262 case Intrinsic::x86_avx512_mask_min_ss_round:
3263 case Intrinsic::x86_avx512_mask_add_sd_round:
3264 case Intrinsic::x86_avx512_mask_div_sd_round:
3265 case Intrinsic::x86_avx512_mask_mul_sd_round:
3266 case Intrinsic::x86_avx512_mask_sub_sd_round:
3267 case Intrinsic::x86_avx512_mask_max_sd_round:
3268 case Intrinsic::x86_avx512_mask_min_sd_round:
3269 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3270
3271 // If lowest element of a scalar op isn't used then use Arg0.
3272 if (!DemandedElts[0]) {
3273 IC.addToWorklist(I: &II);
3274 return II.getArgOperand(i: 0);
3275 }
3276
3277 // Only lower element is used for operand 1 and 2.
3278 DemandedElts = 1;
3279 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
3280 simplifyAndSetOp(&II, 2, DemandedElts, UndefElts3);
3281
3282 // Lower element is undefined if all three lower elements are undefined.
3283 // Consider things like undef&0. The result is known zero, not undef.
3284 if (!UndefElts2[0] || !UndefElts3[0])
3285 UndefElts.clearBit(BitPosition: 0);
3286 break;
3287
3288 // TODO: Add fmaddsub support?
3289 case Intrinsic::x86_sse3_addsub_pd:
3290 case Intrinsic::x86_sse3_addsub_ps:
3291 case Intrinsic::x86_avx_addsub_pd_256:
3292 case Intrinsic::x86_avx_addsub_ps_256: {
3293 // If none of the even or none of the odd lanes are required, turn this
3294 // into a generic FP math instruction.
3295 APInt SubMask = APInt::getSplat(NewLen: VWidth, V: APInt(2, 0x1));
3296 APInt AddMask = APInt::getSplat(NewLen: VWidth, V: APInt(2, 0x2));
3297 bool IsSubOnly = DemandedElts.isSubsetOf(RHS: SubMask);
3298 bool IsAddOnly = DemandedElts.isSubsetOf(RHS: AddMask);
3299 if (IsSubOnly || IsAddOnly) {
3300 assert((IsSubOnly ^ IsAddOnly) && "Can't be both add-only and sub-only");
3301 IRBuilderBase::InsertPointGuard Guard(IC.Builder);
3302 IC.Builder.SetInsertPoint(&II);
3303 Value *Arg0 = II.getArgOperand(i: 0), *Arg1 = II.getArgOperand(i: 1);
3304 return IC.Builder.CreateBinOp(
3305 Opc: IsSubOnly ? Instruction::FSub : Instruction::FAdd, LHS: Arg0, RHS: Arg1);
3306 }
3307
3308 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3309 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
3310 UndefElts &= UndefElts2;
3311 break;
3312 }
3313
3314 // General per-element vector operations.
3315 case Intrinsic::x86_avx2_psllv_d:
3316 case Intrinsic::x86_avx2_psllv_d_256:
3317 case Intrinsic::x86_avx2_psllv_q:
3318 case Intrinsic::x86_avx2_psllv_q_256:
3319 case Intrinsic::x86_avx2_psrlv_d:
3320 case Intrinsic::x86_avx2_psrlv_d_256:
3321 case Intrinsic::x86_avx2_psrlv_q:
3322 case Intrinsic::x86_avx2_psrlv_q_256:
3323 case Intrinsic::x86_avx2_psrav_d:
3324 case Intrinsic::x86_avx2_psrav_d_256: {
3325 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3326 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
3327 UndefElts &= UndefElts2;
3328 break;
3329 }
3330
3331 case Intrinsic::x86_ssse3_pmul_hr_sw_128:
3332 case Intrinsic::x86_avx2_pmul_hr_sw:
3333 case Intrinsic::x86_avx512_pmul_hr_sw_512: {
3334 simplifyAndSetOp(&II, 0, DemandedElts, UndefElts);
3335 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts2);
3336 // NOTE: mulh(undef,undef) != undef.
3337 break;
3338 }
3339
3340 case Intrinsic::x86_sse2_packssdw_128:
3341 case Intrinsic::x86_sse2_packsswb_128:
3342 case Intrinsic::x86_sse2_packuswb_128:
3343 case Intrinsic::x86_sse41_packusdw:
3344 case Intrinsic::x86_avx2_packssdw:
3345 case Intrinsic::x86_avx2_packsswb:
3346 case Intrinsic::x86_avx2_packusdw:
3347 case Intrinsic::x86_avx2_packuswb:
3348 case Intrinsic::x86_avx512_packssdw_512:
3349 case Intrinsic::x86_avx512_packsswb_512:
3350 case Intrinsic::x86_avx512_packusdw_512:
3351 case Intrinsic::x86_avx512_packuswb_512: {
3352 auto *Ty0 = II.getArgOperand(i: 0)->getType();
3353 unsigned InnerVWidth = cast<FixedVectorType>(Val: Ty0)->getNumElements();
3354 assert(VWidth == (InnerVWidth * 2) && "Unexpected input size");
3355
3356 unsigned NumLanes = Ty0->getPrimitiveSizeInBits() / 128;
3357 unsigned VWidthPerLane = VWidth / NumLanes;
3358 unsigned InnerVWidthPerLane = InnerVWidth / NumLanes;
3359
3360 // Per lane, pack the elements of the first input and then the second.
3361 // e.g.
3362 // v8i16 PACK(v4i32 X, v4i32 Y) - (X[0..3],Y[0..3])
3363 // v32i8 PACK(v16i16 X, v16i16 Y) - (X[0..7],Y[0..7]),(X[8..15],Y[8..15])
3364 for (int OpNum = 0; OpNum != 2; ++OpNum) {
3365 APInt OpDemandedElts(InnerVWidth, 0);
3366 for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
3367 unsigned LaneIdx = Lane * VWidthPerLane;
3368 for (unsigned Elt = 0; Elt != InnerVWidthPerLane; ++Elt) {
3369 unsigned Idx = LaneIdx + Elt + InnerVWidthPerLane * OpNum;
3370 if (DemandedElts[Idx])
3371 OpDemandedElts.setBit((Lane * InnerVWidthPerLane) + Elt);
3372 }
3373 }
3374
3375 // Demand elements from the operand.
3376 APInt OpUndefElts(InnerVWidth, 0);
3377 simplifyAndSetOp(&II, OpNum, OpDemandedElts, OpUndefElts);
3378
3379 // Pack the operand's UNDEF elements, one lane at a time.
3380 OpUndefElts = OpUndefElts.zext(width: VWidth);
3381 for (unsigned Lane = 0; Lane != NumLanes; ++Lane) {
3382 APInt LaneElts = OpUndefElts.lshr(shiftAmt: InnerVWidthPerLane * Lane);
3383 LaneElts = LaneElts.getLoBits(numBits: InnerVWidthPerLane);
3384 LaneElts <<= InnerVWidthPerLane * (2 * Lane + OpNum);
3385 UndefElts |= LaneElts;
3386 }
3387 }
3388 break;
3389 }
3390
3391 case Intrinsic::x86_sse2_pmadd_wd:
3392 case Intrinsic::x86_avx2_pmadd_wd:
3393 case Intrinsic::x86_avx512_pmaddw_d_512:
3394 case Intrinsic::x86_ssse3_pmadd_ub_sw_128:
3395 case Intrinsic::x86_avx2_pmadd_ub_sw:
3396 case Intrinsic::x86_avx512_pmaddubs_w_512: {
3397 // PMADD - demand both src elements that map to each dst element.
3398 auto *ArgTy = II.getArgOperand(i: 0)->getType();
3399 unsigned InnerVWidth = cast<FixedVectorType>(Val: ArgTy)->getNumElements();
3400 assert((VWidth * 2) == InnerVWidth && "Unexpected input size");
3401 APInt OpDemandedElts = APIntOps::ScaleBitMask(A: DemandedElts, NewBitWidth: InnerVWidth);
3402 APInt Op0UndefElts(InnerVWidth, 0);
3403 APInt Op1UndefElts(InnerVWidth, 0);
3404 simplifyAndSetOp(&II, 0, OpDemandedElts, Op0UndefElts);
3405 simplifyAndSetOp(&II, 1, OpDemandedElts, Op1UndefElts);
3406 // NOTE: madd(undef,undef) != undef.
3407 break;
3408 }
3409
3410 // PSHUFB
3411 case Intrinsic::x86_ssse3_pshuf_b_128:
3412 case Intrinsic::x86_avx2_pshuf_b:
3413 case Intrinsic::x86_avx512_pshuf_b_512:
3414 // PERMILVAR
3415 case Intrinsic::x86_avx_vpermilvar_ps:
3416 case Intrinsic::x86_avx_vpermilvar_ps_256:
3417 case Intrinsic::x86_avx512_vpermilvar_ps_512:
3418 case Intrinsic::x86_avx_vpermilvar_pd:
3419 case Intrinsic::x86_avx_vpermilvar_pd_256:
3420 case Intrinsic::x86_avx512_vpermilvar_pd_512:
3421 // PERMV
3422 case Intrinsic::x86_avx2_permd:
3423 case Intrinsic::x86_avx2_permps: {
3424 simplifyAndSetOp(&II, 1, DemandedElts, UndefElts);
3425 break;
3426 }
3427
3428 // SSE4A instructions leave the upper 64-bits of the 128-bit result
3429 // in an undefined state.
3430 case Intrinsic::x86_sse4a_extrq:
3431 case Intrinsic::x86_sse4a_extrqi:
3432 case Intrinsic::x86_sse4a_insertq:
3433 case Intrinsic::x86_sse4a_insertqi:
3434 UndefElts.setHighBits(VWidth / 2);
3435 break;
3436 }
3437 return std::nullopt;
3438}
3439