Skip to content

Commit 88d3b99

Browse files
committed
[Headers][X86] Allow AVX512 masked arithmetic intrinsics to be used in constexpr
1 parent 0df4e63 commit 88d3b99

File tree

7 files changed

+197
-120
lines changed

7 files changed

+197
-120
lines changed

clang/include/clang/Basic/BuiltinsX86.td

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4104,7 +4104,7 @@ let Features = "avx512bf16", Attributes = [NoThrow, Const, RequiredVectorWidth<1
41044104
def selectsbf_128 : X86Builtin<"_Vector<8, __bf16>(unsigned char, _Vector<8, __bf16>, _Vector<8, __bf16>)">;
41054105
}
41064106

4107-
let Features = "avx512f", Attributes = [NoThrow, Const, RequiredVectorWidth<128>] in {
4107+
let Features = "avx512f", Attributes = [NoThrow, Const, Constexpr, RequiredVectorWidth<128>] in {
41084108
def selectss_128 : X86Builtin<"_Vector<4, float>(unsigned char, _Vector<4, float>, _Vector<4, float>)">;
41094109
def selectsd_128 : X86Builtin<"_Vector<2, double>(unsigned char, _Vector<2, double>, _Vector<2, double>)">;
41104110
}

clang/lib/AST/ByteCode/InterpBuiltin.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3598,6 +3598,27 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
35983598
return APInt::getAllOnes(DstBits);
35993599
});
36003600

3601+
case clang::X86::BI__builtin_ia32_selectss_128:
3602+
case clang::X86::BI__builtin_ia32_selectsd_128: {
3603+
const unsigned N =
3604+
Call->getArg(1)->getType()->getAs<VectorType>()->getNumElements();
3605+
3606+
const Pointer &W = S.Stk.pop<Pointer>();
3607+
const Pointer &A = S.Stk.pop<Pointer>();
3608+
APSInt U = popToAPSInt(S, Call->getArg(0));
3609+
const Pointer &Dst = S.Stk.peek<Pointer>();
3610+
3611+
const bool TakeA0 = U.getZExtValue() & 1ULL;
3612+
3613+
for (unsigned i = 0; i < N; ++i)
3614+
Dst.elem<Floating>(i) = W.elem<Floating>(i);
3615+
if (TakeA0)
3616+
Dst.elem<Floating>(0) = A.elem<Floating>(0);
3617+
3618+
Dst.initializeAllElements();
3619+
return true;
3620+
}
3621+
36013622
case clang::X86::BI__builtin_ia32_vprotbi:
36023623
case clang::X86::BI__builtin_ia32_vprotdi:
36033624
case clang::X86::BI__builtin_ia32_vprotqi:

clang/lib/AST/ExprConstant.cpp

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11705,6 +11705,23 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1170511705
return Success(APValue(ResultElements.data(), SourceLen), E);
1170611706
};
1170711707

11708+
auto EvalSelectScalar = [&](unsigned Len) -> std::optional<APValue> {
11709+
APSInt Mask;
11710+
APValue AVal, WVal;
11711+
if (!EvaluateInteger(E->getArg(0), Mask, Info) ||
11712+
!EvaluateAsRValue(Info, E->getArg(1), AVal) ||
11713+
!EvaluateAsRValue(Info, E->getArg(2), WVal))
11714+
return std::nullopt;
11715+
11716+
const bool TakeA0 = (Mask.getZExtValue() & 1u) != 0;
11717+
SmallVector<APValue, 4> Res;
11718+
Res.reserve(Len);
11719+
Res.push_back(TakeA0 ? AVal.getVectorElt(0) : WVal.getVectorElt(0));
11720+
for (unsigned i = 1; i < Len; ++i)
11721+
Res.push_back(WVal.getVectorElt(i));
11722+
return APValue(Res.data(), Res.size());
11723+
};
11724+
1170811725
switch (E->getBuiltinCallee()) {
1170911726
default:
1171011727
return false;
@@ -11933,6 +11950,16 @@ bool VectorExprEvaluator::VisitCallExpr(const CallExpr *E) {
1193311950
return APInt((Src).trunc(DstBits));
1193411951
return APInt::getAllOnes(DstBits);
1193511952
});
11953+
case clang::X86::BI__builtin_ia32_selectss_128: {
11954+
if (auto V = EvalSelectScalar(4))
11955+
return Success(*V, E);
11956+
return false;
11957+
}
11958+
case clang::X86::BI__builtin_ia32_selectsd_128: {
11959+
if (auto V = EvalSelectScalar(2))
11960+
return Success(*V, E);
11961+
return false;
11962+
}
1193611963
case clang::X86::BI__builtin_ia32_pmuldq128:
1193711964
case clang::X86::BI__builtin_ia32_pmuldq256:
1193811965
case clang::X86::BI__builtin_ia32_pmuldq512:

0 commit comments

Comments
 (0)