[clang] [llvm] [Clang] VectorExprEvaluator::VisitCallExpr / InterpretBuiltin - allow AVX/AVX512 subvector extraction intrinsics to be used in constexpr #157712 (PR #158853)

Timm Baeder via llvm-commits llvm-commits at lists.llvm.org
Mon Oct 6 23:15:34 PDT 2025


================
@@ -2836,6 +2837,99 @@ static bool interp__builtin_elementwise_triop(
   return true;
 }
 
+//_builtin_extract
+static bool interp__builtin_x86_extract_vector(InterpState &S, CodePtr OpPC,
+                                                 const CallExpr *Call,
+                                                 unsigned ID) {
+  assert(Call->getNumArgs() == 2);
+
+  // srcimm
+  APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
+  uint64_t Index = ImmAPS.getZExtValue();
+
+  // srcvec
+  const Pointer &Src = S.Stk.pop<Pointer>();
+  if (!Src.getFieldDesc()->isPrimitiveArray())
+    return false;
+
+  // destination (return value)
+  const Pointer &Dst = S.Stk.peek<Pointer>();
+  if (!Dst.getFieldDesc()->isPrimitiveArray())
+    return false;
+
+  unsigned SrcElems = Src.getNumElems();
+  unsigned DstElems = Dst.getNumElems();
+
+  if (SrcElems == 0 || DstElems == 0 || (SrcElems % DstElems) != 0)
+    return false;
+
+  unsigned NumLanes = SrcElems / DstElems;
+  unsigned Lane = static_cast<unsigned>(Index % NumLanes);
+  unsigned ExtractPos = Lane * DstElems;
+
+  // element type 
+  PrimType ElemPT = Src.getFieldDesc()->getPrimType();
+  if (ElemPT != Dst.getFieldDesc()->getPrimType())
+    return false;
+
+  TYPE_SWITCH(ElemPT, {
+    for (unsigned I = 0; I != DstElems; ++I) {
+      Dst.elem<T>(I) = Src.elem<T>(ExtractPos + I);
+    }
+  });
+
+  Dst.initializeAllElements();
+  return true;
+}
+
+static bool interp__builtin_x86_extract_vector_masked(InterpState &S, CodePtr OpPC,
+                                                      const CallExpr *Call,
+                                                      unsigned ID) {
+  assert(Call->getNumArgs() == 4);
+
+  APSInt UAPS = popToAPSInt(S, Call->getArg(3));
+  const Pointer &W = S.Stk.pop<Pointer>();
+  APSInt ImmAPS = popToAPSInt(S, Call->getArg(1));
+  const Pointer &A = S.Stk.pop<Pointer>();
+
+  if (!A.getFieldDesc()->isPrimitiveArray() || !W.getFieldDesc()->isPrimitiveArray())
+    return false;
+
+  const Pointer &Dst = S.Stk.peek<Pointer>();
+  if (!Dst.getFieldDesc()->isPrimitiveArray())
+    return false;
+
+  unsigned SrcElems = A.getNumElems();
+  unsigned DstElems = Dst.getNumElems();
+  if (!SrcElems || !DstElems || (SrcElems % DstElems) != 0)
+    return false;
+
+  // 타입 일치 체크
+  PrimType PT = A.getFieldDesc()->getPrimType();
----------------
tbaederr wrote:

```suggestion
  PrimType ElemT = A.getFieldDesc()->getPrimType();
```

https://github.com/llvm/llvm-project/pull/158853


More information about the llvm-commits mailing list