From 3f97736181eea7de5ce24beebcbdfd4dcc5c2f09 Mon Sep 17 00:00:00 2001 From: Timm Baeder Date: Thu, 21 Aug 2025 16:34:57 +0200 Subject: [PATCH] [clang][bytecode] Implement ia32_select* builtins (#154758) --- clang/lib/AST/ByteCode/InterpBuiltin.cpp | 61 +++++++++++++++++++++++ clang/test/CodeGen/X86/avx512f-builtins.c | 5 ++ 2 files changed, 66 insertions(+) diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp index 2cbebaf7b630..44224c47e1a5 100644 --- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp +++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp @@ -2778,6 +2778,40 @@ static bool interp__builtin_elementwise_fma(InterpState &S, CodePtr OpPC, return true; } +/// AVX512 predicated move: "Result = Mask[] ? LHS[] : RHS[]". +static bool interp__builtin_select(InterpState &S, CodePtr OpPC, + const CallExpr *Call) { + const Pointer &RHS = S.Stk.pop(); + const Pointer &LHS = S.Stk.pop(); + PrimType MaskT = *S.getContext().classify(Call->getArg(0)); + APSInt Mask = popToAPSInt(S.Stk, MaskT); + const Pointer &Dst = S.Stk.peek(); + + assert(LHS.getNumElems() == RHS.getNumElems()); + assert(LHS.getNumElems() == Dst.getNumElems()); + unsigned NumElems = LHS.getNumElems(); + PrimType ElemT = LHS.getFieldDesc()->getPrimType(); + PrimType DstElemT = Dst.getFieldDesc()->getPrimType(); + + for (unsigned I = 0; I != NumElems; ++I) { + if (ElemT == PT_Float) { + assert(DstElemT == PT_Float); + Dst.elem(I) = + Mask[I] ? LHS.elem(I) : RHS.elem(I); + } else { + APSInt Elem; + INT_TYPE_SWITCH(ElemT, { + Elem = Mask[I] ? LHS.elem(I).toAPSInt() : RHS.elem(I).toAPSInt(); + }); + INT_TYPE_SWITCH_NO_BOOL(DstElemT, + { Dst.elem(I) = static_cast(Elem); }); + } + } + Dst.initializeAllElements(); + + return true; +} + bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, uint32_t BuiltinID) { if (!S.getASTContext().BuiltinInfo.isConstantEvaluated(BuiltinID)) @@ -3210,9 +3244,36 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call, case clang::X86::BI__builtin_ia32_pmuludq256: case clang::X86::BI__builtin_ia32_pmuludq512: return interp__builtin_ia32_pmul(S, OpPC, Call, BuiltinID); + case Builtin::BI__builtin_elementwise_fma: return interp__builtin_elementwise_fma(S, OpPC, Call); + case X86::BI__builtin_ia32_selectb_128: + case X86::BI__builtin_ia32_selectb_256: + case X86::BI__builtin_ia32_selectb_512: + case X86::BI__builtin_ia32_selectw_128: + case X86::BI__builtin_ia32_selectw_256: + case X86::BI__builtin_ia32_selectw_512: + case X86::BI__builtin_ia32_selectd_128: + case X86::BI__builtin_ia32_selectd_256: + case X86::BI__builtin_ia32_selectd_512: + case X86::BI__builtin_ia32_selectq_128: + case X86::BI__builtin_ia32_selectq_256: + case X86::BI__builtin_ia32_selectq_512: + case X86::BI__builtin_ia32_selectph_128: + case X86::BI__builtin_ia32_selectph_256: + case X86::BI__builtin_ia32_selectph_512: + case X86::BI__builtin_ia32_selectpbf_128: + case X86::BI__builtin_ia32_selectpbf_256: + case X86::BI__builtin_ia32_selectpbf_512: + case X86::BI__builtin_ia32_selectps_128: + case X86::BI__builtin_ia32_selectps_256: + case X86::BI__builtin_ia32_selectps_512: + case X86::BI__builtin_ia32_selectpd_128: + case X86::BI__builtin_ia32_selectpd_256: + case X86::BI__builtin_ia32_selectpd_512: + return interp__builtin_select(S, OpPC, Call); + default: S.FFDiag(S.Current->getLocation(OpPC), diag::note_invalid_subexpr_in_const_expr) diff --git a/clang/test/CodeGen/X86/avx512f-builtins.c b/clang/test/CodeGen/X86/avx512f-builtins.c index 14a4bbf712f8..29916be23cba 100644 --- a/clang/test/CodeGen/X86/avx512f-builtins.c +++ b/clang/test/CodeGen/X86/avx512f-builtins.c @@ -3,6 +3,11 @@ // RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -emit-llvm -o - -Wall -Werror -Wsign-conversion | FileCheck %s // RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +avx512f -emit-llvm -o - -Wall -Werror -Wsign-conversion | FileCheck %s +// RUN: %clang_cc1 -x c -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -emit-llvm -o - -Wall -Werror -Wsign-conversion -fexperimental-new-constant-interpreter | FileCheck %s +// RUN: %clang_cc1 -x c -flax-vector-conversions=none -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +avx512f -emit-llvm -o - -Wall -Werror -Wsign-conversion -fexperimental-new-constant-interpreter | FileCheck %s +// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -ffreestanding %s -triple=x86_64-apple-darwin -target-feature +avx512f -emit-llvm -o - -Wall -Werror -Wsign-conversion -fexperimental-new-constant-interpreter | FileCheck %s +// RUN: %clang_cc1 -x c++ -flax-vector-conversions=none -fms-extensions -fms-compatibility -ffreestanding %s -triple=x86_64-windows-msvc -target-feature +avx512f -emit-llvm -o - -Wall -Werror -Wsign-conversion -fexperimental-new-constant-interpreter | FileCheck %s + #include #include "builtin_test_helpers.h"