Skip to content
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions clang/include/clang/Basic/BuiltinsX86.td
Original file line number Diff line number Diff line change
Expand Up @@ -2409,28 +2409,36 @@ let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<512>
def psraq512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<2, long long int>)">;
def psrld512 : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<4, int>)">;
def psrlq512 : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<2, long long int>)">;
}

let Features = "avx512f",
Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<512>] in {
def pternlogd512_mask : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>, _Constant int, unsigned short)">;
def pternlogd512_maskz : X86Builtin<"_Vector<16, int>(_Vector<16, int>, _Vector<16, int>, _Vector<16, int>, _Constant int, unsigned short)">;
def pternlogq512_mask : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>, _Vector<8, long long int>, _Constant int, unsigned char)">;
def pternlogq512_maskz : X86Builtin<"_Vector<8, long long int>(_Vector<8, long long int>, _Vector<8, long long int>, _Vector<8, long long int>, _Constant int, unsigned char)">;
}

let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
let Features = "avx512vl",
Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
def pternlogd128_mask : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>, _Constant int, unsigned char)">;
def pternlogd128_maskz : X86Builtin<"_Vector<4, int>(_Vector<4, int>, _Vector<4, int>, _Vector<4, int>, _Constant int, unsigned char)">;
}

let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
let Features = "avx512vl",
Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
def pternlogd256_mask : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>, _Constant int, unsigned char)">;
def pternlogd256_maskz : X86Builtin<"_Vector<8, int>(_Vector<8, int>, _Vector<8, int>, _Vector<8, int>, _Constant int, unsigned char)">;
}

let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
let Features = "avx512vl",
Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
def pternlogq128_mask : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>, _Vector<2, long long int>, _Constant int, unsigned char)">;
def pternlogq128_maskz : X86Builtin<"_Vector<2, long long int>(_Vector<2, long long int>, _Vector<2, long long int>, _Vector<2, long long int>, _Constant int, unsigned char)">;
}

let Features = "avx512vl", Attributes = [NoThrow, Const, RequiredVectorWidth<256>] in {
let Features = "avx512vl",
Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<256>] in {
def pternlogq256_mask : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Vector<4, long long int>, _Constant int, unsigned char)">;
def pternlogq256_maskz : X86Builtin<"_Vector<4, long long int>(_Vector<4, long long int>, _Vector<4, long long int>, _Vector<4, long long int>, _Constant int, unsigned char)">;
}
Expand Down
56 changes: 56 additions & 0 deletions clang/lib/AST/ByteCode/InterpBuiltin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2918,7 +2918,49 @@ static bool interp__builtin_x86_insert_subvector(InterpState &S, CodePtr OpPC,
});

Dst.initializeAllElements();
return true;
}

static bool interp__builtin_ia32_pternlog(InterpState &S, CodePtr OpPC,
const CallExpr *Call, bool MaskZ) {
assert(Call->getNumArgs() == 5);

APInt U = popToAPSInt(S, Call->getArg(4)); // Lane mask
APInt Imm = popToAPSInt(S, Call->getArg(3)); // Ternary truth table
const Pointer &C = S.Stk.pop<Pointer>();
const Pointer &B = S.Stk.pop<Pointer>();
const Pointer &A = S.Stk.pop<Pointer>();
const Pointer &Dst = S.Stk.peek<Pointer>();

unsigned DstLen = A.getNumElems();
const QualType ElemQT = getElemType(A);
const OptPrimType ElemPT = S.getContext().classify(ElemQT);
unsigned LaneWidth = S.getASTContext().getTypeSize(ElemQT);
bool DstUnsigned = ElemQT->isUnsignedIntegerOrEnumerationType();

INT_TYPE_SWITCH_NO_BOOL(*ElemPT, {
for (unsigned I = 0; I != DstLen; ++I) {
APInt ALane = A.elem<T>(I).toAPSInt();
APInt BLane = B.elem<T>(I).toAPSInt();
APInt CLane = C.elem<T>(I).toAPSInt();
APInt RLane(LaneWidth, 0);
if (U[I]) { // If lane not masked, compute ternary logic.
for (unsigned Bit = 0; Bit != LaneWidth; ++Bit) {
unsigned ABit = ALane[Bit];
unsigned BBit = BLane[Bit];
unsigned CBit = CLane[Bit];
unsigned Idx = (ABit << 2) | (BBit << 1) | (CBit);
RLane.setBitVal(Bit, Imm[Idx]);
}
Dst.elem<T>(I) = static_cast<T>(APSInt(RLane, DstUnsigned));
} else if (MaskZ) { // If zero masked, zero the lane.
Dst.elem<T>(I) = static_cast<T>(APSInt(RLane, DstUnsigned));
} else { // Just masked, put in A lane.
Dst.elem<T>(I) = static_cast<T>(APSInt(ALane, DstUnsigned));
}
}
});
Dst.initializeAllElements();
return true;
}

Expand Down Expand Up @@ -3775,6 +3817,20 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
S, OpPC, Call,
[](const APSInt &LHS, const APSInt &RHS) { return LHS + RHS; });

case X86::BI__builtin_ia32_pternlogd128_mask:
case X86::BI__builtin_ia32_pternlogd256_mask:
case X86::BI__builtin_ia32_pternlogd512_mask:
case X86::BI__builtin_ia32_pternlogq128_mask:
case X86::BI__builtin_ia32_pternlogq256_mask:
case X86::BI__builtin_ia32_pternlogq512_mask:
return interp__builtin_ia32_pternlog(S, OpPC, Call, /*MaskZ=*/false);
case X86::BI__builtin_ia32_pternlogd128_maskz:
case X86::BI__builtin_ia32_pternlogd256_maskz:
case X86::BI__builtin_ia32_pternlogd512_maskz:
case X86::BI__builtin_ia32_pternlogq128_maskz:
case X86::BI__builtin_ia32_pternlogq256_maskz:
case X86::BI__builtin_ia32_pternlogq512_maskz:
return interp__builtin_ia32_pternlog(S, OpPC, Call, /*MaskZ=*/true);
case Builtin::BI__builtin_elementwise_fshl:
return interp__builtin_elementwise_triop(S, OpPC, Call,
llvm::APIntOps::fshl);
Expand Down
91 changes: 91 additions & 0 deletions clang/lib/AST/ExprConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12168,6 +12168,97 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
return Success(R, E);
}

case X86::BI__builtin_ia32_pternlogd128_mask:
case X86::BI__builtin_ia32_pternlogd256_mask:
case X86::BI__builtin_ia32_pternlogd512_mask:
case X86::BI__builtin_ia32_pternlogq128_mask:
case X86::BI__builtin_ia32_pternlogq256_mask:
case X86::BI__builtin_ia32_pternlogq512_mask: {
APValue AValue, BValue, CValue, ImmValue, UValue;
if (!EvaluateAsRValue(Info, E->getArg(0), AValue) ||
!EvaluateAsRValue(Info, E->getArg(1), BValue) ||
!EvaluateAsRValue(Info, E->getArg(2), CValue) ||
!EvaluateAsRValue(Info, E->getArg(3), ImmValue) ||
!EvaluateAsRValue(Info, E->getArg(4), UValue))
return false;

QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
APInt Imm = ImmValue.getInt();
APInt U = UValue.getInt();
unsigned ResultLen = AValue.getVectorLength();
SmallVector<APValue, 16> ResultElements;
ResultElements.reserve(ResultLen);

for (unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
APInt ALane = AValue.getVectorElt(EltNum).getInt();
APInt BLane = BValue.getVectorElt(EltNum).getInt();
APInt CLane = CValue.getVectorElt(EltNum).getInt();

if (U[EltNum]) {
unsigned BitWidth = ALane.getBitWidth();
APInt ResLane(BitWidth, 0);

for (unsigned Bit = 0; Bit < BitWidth; ++Bit) {
unsigned ABit = ALane[Bit];
unsigned BBit = BLane[Bit];
unsigned CBit = CLane[Bit];

unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
ResLane.setBitVal(Bit, Imm[Idx]);
}
ResultElements.push_back(APValue(APSInt(ResLane, DestUnsigned)));
} else {
ResultElements.push_back(APValue(APSInt(ALane, DestUnsigned)));
}
}
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}
case X86::BI__builtin_ia32_pternlogd128_maskz:
case X86::BI__builtin_ia32_pternlogd256_maskz:
case X86::BI__builtin_ia32_pternlogd512_maskz:
case X86::BI__builtin_ia32_pternlogq128_maskz:
case X86::BI__builtin_ia32_pternlogq256_maskz:
case X86::BI__builtin_ia32_pternlogq512_maskz: {
APValue AValue, BValue, CValue, ImmValue, UValue;
if (!EvaluateAsRValue(Info, E->getArg(0), AValue) ||
!EvaluateAsRValue(Info, E->getArg(1), BValue) ||
!EvaluateAsRValue(Info, E->getArg(2), CValue) ||
!EvaluateAsRValue(Info, E->getArg(3), ImmValue) ||
!EvaluateAsRValue(Info, E->getArg(4), UValue))
return false;

QualType DestEltTy = E->getType()->castAs<VectorType>()->getElementType();
bool DestUnsigned = DestEltTy->isUnsignedIntegerOrEnumerationType();
APInt Imm = ImmValue.getInt();
APInt U = UValue.getInt();
unsigned ResultLen = AValue.getVectorLength();
SmallVector<APValue, 16> ResultElements;
ResultElements.reserve(ResultLen);

for (unsigned EltNum = 0; EltNum < ResultLen; ++EltNum) {
APInt ALane = AValue.getVectorElt(EltNum).getInt();
APInt BLane = BValue.getVectorElt(EltNum).getInt();
APInt CLane = CValue.getVectorElt(EltNum).getInt();

unsigned BitWidth = ALane.getBitWidth();
APInt ResLane(BitWidth, 0);

if (U[EltNum]) {
for (unsigned Bit = 0; Bit < BitWidth; ++Bit) {
unsigned ABit = ALane[Bit];
unsigned BBit = BLane[Bit];
unsigned CBit = CLane[Bit];

unsigned Idx = (ABit << 2) | (BBit << 1) | CBit;
ResLane.setBitVal(Bit, Imm[Idx]);
}
}
ResultElements.push_back(APValue(APSInt(ResLane, DestUnsigned)));
}
return Success(APValue(ResultElements.data(), ResultElements.size()), E);
}

case Builtin::BI__builtin_elementwise_clzg:
case Builtin::BI__builtin_elementwise_ctzg: {
APValue SourceLHS;
Expand Down
Loading