[clang] [compiler-rt] [X86] Remove x86 PDEP/PEXT clang intrinsics and rely on generic elementwise implementations (PR #204969)

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 7 23:11:33 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-clang-codegen

Author: Simon Pilgrim (RKSimon)

<details>
<summary>Changes</summary>



---
Full diff: https://github.com/llvm/llvm-project/pull/204969.diff


7 Files Affected:

- (modified) clang/include/clang/Basic/BuiltinsX86.td (-2) 
- (modified) clang/include/clang/Basic/BuiltinsX86_64.td (-2) 
- (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+9-12) 
- (modified) clang/lib/AST/ExprConstant.cpp (+1-4) 
- (modified) clang/lib/CodeGen/TargetBuiltins/X86.cpp (-10) 
- (modified) clang/lib/Headers/bmi2intrin.h (+4-4) 
- (modified) compiler-rt/lib/msan/tests/msan_test.cpp (+29-28) 


``````````diff
diff --git a/clang/include/clang/Basic/BuiltinsX86.td b/clang/include/clang/Basic/BuiltinsX86.td
index 04f93db3aa0b0..82ce6302999c7 100644
--- a/clang/include/clang/Basic/BuiltinsX86.td
+++ b/clang/include/clang/Basic/BuiltinsX86.td
@@ -816,8 +816,6 @@ let Attributes = [NoThrow, Const, Constexpr] in {
 
 let Features = "bmi2", Attributes = [NoThrow, Const, Constexpr] in {
   def bzhi_si : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
-  def pdep_si : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
-  def pext_si : X86Builtin<"unsigned int(unsigned int, unsigned int)">;
 }
 
 let Features = "tbm", Attributes = [NoThrow, Const, Constexpr] in {
diff --git a/clang/include/clang/Basic/BuiltinsX86_64.td b/clang/include/clang/Basic/BuiltinsX86_64.td
index cf76d9a257614..bf8ddd6559cde 100644
--- a/clang/include/clang/Basic/BuiltinsX86_64.td
+++ b/clang/include/clang/Basic/BuiltinsX86_64.td
@@ -137,8 +137,6 @@ let Attributes = [NoThrow, Const, Constexpr] in {
 
 let Features = "bmi2", Attributes = [NoThrow, Const, Constexpr] in {
   def bzhi_di : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
-  def pdep_di : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
-  def pext_di : X86Builtin<"unsigned long long int(unsigned long long int, unsigned long long int)">;
 }
 
 let Features = "tbm", Attributes = [NoThrow, Const, Constexpr] in {
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index b78ce614e290d..0ddbd1f57b421 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -5264,18 +5264,6 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
           return APInt(Src.getBitWidth(), Src.countTrailingZeros());
         });
 
-  case clang::X86::BI__builtin_ia32_pdep_si:
-  case clang::X86::BI__builtin_ia32_pdep_di:
-  case Builtin::BI__builtin_elementwise_pdep:
-    return interp__builtin_elementwise_int_binop(S, OpPC, Call,
-                                                 llvm::APIntOps::pdep);
-
-  case clang::X86::BI__builtin_ia32_pext_si:
-  case clang::X86::BI__builtin_ia32_pext_di:
-  case Builtin::BI__builtin_elementwise_pext:
-    return interp__builtin_elementwise_int_binop(S, OpPC, Call,
-                                                 llvm::APIntOps::pext);
-
   case clang::X86::BI__builtin_ia32_addcarryx_u32:
   case clang::X86::BI__builtin_ia32_addcarryx_u64:
     return interp__builtin_ia32_addcarry_subborrow(S, OpPC, Frame, Call,
@@ -5379,6 +5367,15 @@ bool InterpretBuiltin(InterpState &S, CodePtr OpPC, const CallExpr *Call,
         S, OpPC, Call, [](const APSInt &LHS, const APSInt &RHS) {
           return LHS.isSigned() ? LHS.ssub_sat(RHS) : LHS.usub_sat(RHS);
         });
+
+  case Builtin::BI__builtin_elementwise_pdep:
+    return interp__builtin_elementwise_int_binop(S, OpPC, Call,
+                                                 llvm::APIntOps::pdep);
+
+  case Builtin::BI__builtin_elementwise_pext:
+    return interp__builtin_elementwise_int_binop(S, OpPC, Call,
+                                                 llvm::APIntOps::pext);
+
   case X86::BI__builtin_ia32_extract128i256:
   case X86::BI__builtin_ia32_vextractf128_pd256:
   case X86::BI__builtin_ia32_vextractf128_ps256:
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 43d49da015d4e..cc992309bc7a8 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -18465,8 +18465,6 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     return Success(Val.countTrailingZeros(), E);
   }
 
-  case clang::X86::BI__builtin_ia32_pdep_si:
-  case clang::X86::BI__builtin_ia32_pdep_di:
   case Builtin::BI__builtin_elementwise_pdep: {
     APSInt Val, Msk;
     if (!EvaluateInteger(E->getArg(0), Val, Info) ||
@@ -18475,8 +18473,6 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
     return Success(llvm::APIntOps::pdep(Val, Msk), E);
   }
 
-  case clang::X86::BI__builtin_ia32_pext_si:
-  case clang::X86::BI__builtin_ia32_pext_di:
   case Builtin::BI__builtin_elementwise_pext: {
     APSInt Val, Msk;
     if (!EvaluateInteger(E->getArg(0), Val, Info) ||
@@ -18484,6 +18480,7 @@ bool IntExprEvaluator::VisitBuiltinCallExpr(const CallExpr *E,
       return false;
     return Success(llvm::APIntOps::pext(Val, Msk), E);
   }
+
   case X86::BI__builtin_ia32_ptestz128:
   case X86::BI__builtin_ia32_ptestz256:
   case X86::BI__builtin_ia32_vtestzps:
diff --git a/clang/lib/CodeGen/TargetBuiltins/X86.cpp b/clang/lib/CodeGen/TargetBuiltins/X86.cpp
index 0e675421d4278..5771f10da1d5f 100644
--- a/clang/lib/CodeGen/TargetBuiltins/X86.cpp
+++ b/clang/lib/CodeGen/TargetBuiltins/X86.cpp
@@ -969,16 +969,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
     Function *F = CGM.getIntrinsic(Intrinsic::cttz, Ops[0]->getType());
     return Builder.CreateCall(F, {Ops[0], Builder.getInt1(false)});
   }
-  case X86::BI__builtin_ia32_pdep_si:
-  case X86::BI__builtin_ia32_pdep_di: {
-    Function *F = CGM.getIntrinsic(Intrinsic::pdep, Ops[0]->getType());
-    return Builder.CreateCall(F, Ops);
-  }
-  case X86::BI__builtin_ia32_pext_si:
-  case X86::BI__builtin_ia32_pext_di: {
-    Function *F = CGM.getIntrinsic(Intrinsic::pext, Ops[0]->getType());
-    return Builder.CreateCall(F, Ops);
-  }
   case X86::BI__builtin_ia32_undef128:
   case X86::BI__builtin_ia32_undef256:
   case X86::BI__builtin_ia32_undef512:
diff --git a/clang/lib/Headers/bmi2intrin.h b/clang/lib/Headers/bmi2intrin.h
index bdb61b13fb83b..38e6d1d28da8b 100644
--- a/clang/lib/Headers/bmi2intrin.h
+++ b/clang/lib/Headers/bmi2intrin.h
@@ -74,7 +74,7 @@ _bzhi_u32(unsigned int __X, unsigned int __Y) {
 /// \returns The 32-bit result.
 static __inline__ unsigned int __DEFAULT_FN_ATTRS
 _pdep_u32(unsigned int __X, unsigned int __Y) {
-  return __builtin_ia32_pdep_si(__X, __Y);
+  return __builtin_elementwise_pdep(__X, __Y);
 }
 
 /// Extract (gather) bits from the unsigned 32-bit integer \a __X into the
@@ -103,7 +103,7 @@ _pdep_u32(unsigned int __X, unsigned int __Y) {
 /// \returns The 32-bit result.
 static __inline__ unsigned int __DEFAULT_FN_ATTRS
 _pext_u32(unsigned int __X, unsigned int __Y) {
-  return __builtin_ia32_pext_si(__X, __Y);
+  return __builtin_elementwise_pext(__X, __Y);
 }
 
 /// Multiplies the unsigned 32-bit integers \a __X and \a __Y to form a
@@ -186,7 +186,7 @@ _bzhi_u64(unsigned long long __X, unsigned long long __Y) {
 /// \returns The 64-bit result.
 static __inline__ unsigned long long __DEFAULT_FN_ATTRS
 _pdep_u64(unsigned long long __X, unsigned long long __Y) {
-  return __builtin_ia32_pdep_di(__X, __Y);
+  return __builtin_elementwise_pdep(__X, __Y);
 }
 
 /// Extract (gather) bits from the unsigned 64-bit integer \a __X into the
@@ -215,7 +215,7 @@ _pdep_u64(unsigned long long __X, unsigned long long __Y) {
 /// \returns The 64-bit result.
 static __inline__ unsigned long long __DEFAULT_FN_ATTRS
 _pext_u64(unsigned long long __X, unsigned long long __Y) {
-  return __builtin_ia32_pext_di(__X, __Y);
+  return __builtin_elementwise_pext(__X, __Y);
 }
 
 /// Multiplies the unsigned 64-bit integers \a __X and \a __Y to form a
diff --git a/compiler-rt/lib/msan/tests/msan_test.cpp b/compiler-rt/lib/msan/tests/msan_test.cpp
index e5f64716ededc..fcfc9ea9d09a6 100644
--- a/compiler-rt/lib/msan/tests/msan_test.cpp
+++ b/compiler-rt/lib/msan/tests/msan_test.cpp
@@ -4834,43 +4834,44 @@ static void TestBEXTR() {
 __attribute__((target("bmi,bmi2")))
 static void TestPDEP() {
   U4 x = Poisoned<U4>(0, 0xFF00);
-  EXPECT_NOT_POISONED(__builtin_ia32_pdep_si(x, 0xFF));
-  EXPECT_POISONED(__builtin_ia32_pdep_si(x, 0x1FF));
-  EXPECT_NOT_POISONED(__builtin_ia32_pdep_si(x, 0xFF00));
-  EXPECT_POISONED(__builtin_ia32_pdep_si(x, 0x1FF00));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pdep(x, 0xFFu));
+  EXPECT_POISONED(__builtin_elementwise_pdep(x, 0x1FFu));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pdep(x, 0xFF00u));
+  EXPECT_POISONED(__builtin_elementwise_pdep(x, 0x1FF00u));
 
-  EXPECT_NOT_POISONED(__builtin_ia32_pdep_si(x, 0x1FF00) & 0xFF);
-  EXPECT_POISONED(__builtin_ia32_pdep_si(0, Poisoned<U4>(0xF, 1)));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pdep(x, 0x1FF00u) & 0xFFu);
+  EXPECT_POISONED(__builtin_elementwise_pdep(0u, Poisoned<U4>(0xF, 1)));
 
   U8 y = Poisoned<U8>(0, 0xFF00);
-  EXPECT_NOT_POISONED(__builtin_ia32_pdep_di(y, 0xFF));
-  EXPECT_POISONED(__builtin_ia32_pdep_di(y, 0x1FF));
-  EXPECT_NOT_POISONED(__builtin_ia32_pdep_di(y, 0xFF0000000000));
-  EXPECT_POISONED(__builtin_ia32_pdep_di(y, 0x1FF000000000000));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pdep(y, 0xFFull));
+  EXPECT_POISONED(__builtin_elementwise_pdep(y, 0x1FFull));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pdep(y, 0xFF0000000000ull));
+  EXPECT_POISONED(__builtin_elementwise_pdep(y, 0x1FF000000000000ull));
 
-  EXPECT_NOT_POISONED(__builtin_ia32_pdep_di(y, 0x1FF00) & 0xFF);
-  EXPECT_POISONED(__builtin_ia32_pdep_di(0, Poisoned<U4>(0xF, 1)));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pdep(y, 0x1FF00ull) & 0xFF);
+  EXPECT_POISONED(__builtin_elementwise_pdep(0u, Poisoned<U4>(0xF, 1ull)));
 }
 
 __attribute__((target("bmi,bmi2")))
 static void TestPEXT() {
   U4 x = Poisoned<U4>(0, 0xFF00);
-  EXPECT_NOT_POISONED(__builtin_ia32_pext_si(x, 0xFF));
-  EXPECT_POISONED(__builtin_ia32_pext_si(x, 0x1FF));
-  EXPECT_POISONED(__builtin_ia32_pext_si(x, 0x100));
-  EXPECT_POISONED(__builtin_ia32_pext_si(x, 0x1000));
-  EXPECT_NOT_POISONED(__builtin_ia32_pext_si(x, 0x10000));
-
-  EXPECT_POISONED(__builtin_ia32_pext_si(0xFF00, Poisoned<U4>(0xFF, 1)));
-
-  U8 y = Poisoned<U8>(0, 0xFF0000000000);
-  EXPECT_NOT_POISONED(__builtin_ia32_pext_di(y, 0xFF00000000));
-  EXPECT_POISONED(__builtin_ia32_pext_di(y, 0x1FF00000000));
-  EXPECT_POISONED(__builtin_ia32_pext_di(y, 0x10000000000));
-  EXPECT_POISONED(__builtin_ia32_pext_di(y, 0x100000000000));
-  EXPECT_NOT_POISONED(__builtin_ia32_pext_di(y, 0x1000000000000));
-
-  EXPECT_POISONED(__builtin_ia32_pext_di(0xFF00, Poisoned<U8>(0xFF, 1)));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pext(x, 0xFFu));
+  EXPECT_POISONED(__builtin_elementwise_pext(x, 0x1FFu));
+  EXPECT_POISONED(__builtin_elementwise_pext(x, 0x100u));
+  EXPECT_POISONED(__builtin_elementwise_pext(x, 0x1000u));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pext(x, 0x10000u));
+
+  EXPECT_POISONED(__builtin_elementwise_pext(0xFF00u, Poisoned<U4>(0xFF, 1)));
+
+  U8 y = Poisoned<U8>(0, 0xFF0000000000ull);
+  EXPECT_NOT_POISONED(__builtin_elementwise_pext(y, 0xFF00000000ull));
+  EXPECT_POISONED(__builtin_elementwise_pext(y, 0x1FF00000000ull));
+  EXPECT_POISONED(__builtin_elementwise_pext(y, 0x10000000000ull));
+  EXPECT_POISONED(__builtin_elementwise_pext(y, 0x100000000000ull));
+  EXPECT_NOT_POISONED(__builtin_elementwise_pext(y, 0x1000000000000ull));
+
+  EXPECT_POISONED(
+      __builtin_elementwise_pext(0xFF00ull, Poisoned<U8>(0xFF, 1ull)));
 }
 
 TEST(MemorySanitizer, Bmi) {

``````````

</details>


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


More information about the cfe-commits mailing list