[llvm] [NFC][VectorUtils] Simplify description of `TriviallyScalaraziable` intrinsics (PR #192505)
Finn Plummer via llvm-commits
llvm-commits at lists.llvm.org
Thu Apr 16 11:24:54 PDT 2026
https://github.com/inbelic created https://github.com/llvm/llvm-project/pull/192505
This pr allows us to specify if an intrinsic is `TriviallyScalarizable` by specifying it in a more idiomatic way as an intrinsic property.
This was suggested here: https://github.com/llvm/llvm-project/issues/120169#issuecomment-3805670982, and would allow for the attached issue to be resolved in a similar manner by having a `TriviallyVectorizable` property as well.
Assisted by: Github Copilot.
>From 68f84d840983338be906eb7173ba5962a8fec7f8 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 14 Apr 2026 21:55:13 +0000
Subject: [PATCH 1/4] define `IntrTriviallyScalarizable` as an intrinsic
property
---
llvm/include/llvm/IR/Intrinsics.h | 5 +++++
llvm/include/llvm/IR/Intrinsics.td | 3 +++
llvm/lib/IR/Intrinsics.cpp | 5 +++++
llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp | 2 ++
llvm/utils/TableGen/Basic/CodeGenIntrinsics.h | 3 +++
llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp | 13 +++++++++++++
6 files changed, 31 insertions(+)
diff --git a/llvm/include/llvm/IR/Intrinsics.h b/llvm/include/llvm/IR/Intrinsics.h
index f25df4f42d418..954c704169e53 100644
--- a/llvm/include/llvm/IR/Intrinsics.h
+++ b/llvm/include/llvm/IR/Intrinsics.h
@@ -83,6 +83,11 @@ namespace Intrinsic {
/// Returns true if the intrinsic can be overloaded.
LLVM_ABI bool isOverloaded(ID id);
+ /// Returns true if the intrinsic is trivially scalarizable.
+ /// This means that the intrinsic's argument types are all scalars for the
+ /// scalar form and all vectors for the vector form.
+ LLVM_ABI bool isTriviallyScalarizable(ID id);
+
/// Returns true if the intrinsic has pretty printed immediate arguments.
LLVM_ABI bool hasPrettyPrintedArgs(ID id);
diff --git a/llvm/include/llvm/IR/Intrinsics.td b/llvm/include/llvm/IR/Intrinsics.td
index 0b0fbf7bffc79..522e89e430bfe 100644
--- a/llvm/include/llvm/IR/Intrinsics.td
+++ b/llvm/include/llvm/IR/Intrinsics.td
@@ -228,6 +228,9 @@ def IntrHasSideEffects : IntrinsicProperty;
// poison.
def IntrNoCreateUndefOrPoison : IntrinsicProperty;
+// This property indicates that the intrinsic is trivially scalarizable.
+def IntrTriviallyScalarizable : IntrinsicProperty;
+
//===----------------------------------------------------------------------===//
// IIT constants and utils
//===----------------------------------------------------------------------===//
diff --git a/llvm/lib/IR/Intrinsics.cpp b/llvm/lib/IR/Intrinsics.cpp
index 0e01529bda711..be5580b1d9da7 100644
--- a/llvm/lib/IR/Intrinsics.cpp
+++ b/llvm/lib/IR/Intrinsics.cpp
@@ -620,6 +620,11 @@ bool Intrinsic::isOverloaded(ID id) {
#include "llvm/IR/IntrinsicImpl.inc"
}
+bool Intrinsic::isTriviallyScalarizable(ID id) {
+#define GET_INTRINSIC_SCALARIZABLE_TABLE
+#include "llvm/IR/IntrinsicImpl.inc"
+}
+
bool Intrinsic::hasPrettyPrintedArgs(ID id){
#define GET_INTRINSIC_PRETTY_PRINT_TABLE
#include "llvm/IR/IntrinsicImpl.inc"
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
index d90fcc25502e2..6239082d35bed 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.cpp
@@ -422,6 +422,8 @@ void CodeGenIntrinsic::setProperty(const Record *R) {
isStrictFP = true;
else if (R->getName() == "IntrNoCreateUndefOrPoison")
isNoCreateUndefOrPoison = true;
+ else if (R->getName() == "IntrTriviallyScalarizable")
+ isTriviallyScalarizable = true;
else if (R->isSubClassOf("NoCapture")) {
unsigned ArgNo = R->getValueAsInt("ArgNo");
addArgAttribute(ArgNo, NoCapture);
diff --git a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
index 305260a7ef4a9..7d2d21382b319 100644
--- a/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
+++ b/llvm/utils/TableGen/Basic/CodeGenIntrinsics.h
@@ -117,6 +117,9 @@ struct CodeGenIntrinsic {
// True if the intrinsic is marked as IntrNoCreateUndefOrPoison.
bool isNoCreateUndefOrPoison = false;
+ // True if the intrinsic is marked as IntrTriviallyScalarizable.
+ bool isTriviallyScalarizable = false;
+
enum ArgAttrKind {
NoCapture,
NoAlias,
diff --git a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
index bda911b50d813..71252f2be64d2 100644
--- a/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
+++ b/llvm/utils/TableGen/Basic/IntrinsicEmitter.cpp
@@ -61,6 +61,8 @@ class IntrinsicEmitter {
raw_ostream &OS);
void EmitIntrinsicToOverloadTable(const CodeGenIntrinsicTable &Ints,
raw_ostream &OS);
+ void EmitIntrinsicToScalarizableTable(const CodeGenIntrinsicTable &Ints,
+ raw_ostream &OS);
void EmitIntrinsicToPrettyPrintTable(const CodeGenIntrinsicTable &Ints,
raw_ostream &OS);
void EmitIntrinsicBitTable(
@@ -112,6 +114,9 @@ void IntrinsicEmitter::run(raw_ostream &OS, bool Enums) {
// Emit the intrinsic ID -> overload table.
EmitIntrinsicToOverloadTable(Ints, OS);
+ // Emit the intrinsic ID -> trivially scalarizable table.
+ EmitIntrinsicToScalarizableTable(Ints, OS);
+
// Emit the intrinsic declaration generator.
EmitGenerator(Ints, OS);
@@ -307,6 +312,14 @@ void IntrinsicEmitter::EmitIntrinsicToOverloadTable(
[](const CodeGenIntrinsic &Int) { return Int.isOverloaded; });
}
+void IntrinsicEmitter::EmitIntrinsicToScalarizableTable(
+ const CodeGenIntrinsicTable &Ints, raw_ostream &OS) {
+ EmitIntrinsicBitTable(
+ Ints, OS, "GET_INTRINSIC_SCALARIZABLE_TABLE", "STable",
+ "Intrinsic ID to trivially scalarizable bitset.",
+ [](const CodeGenIntrinsic &Int) { return Int.isTriviallyScalarizable; });
+}
+
using TypeSigTy = SmallVector<unsigned char>;
/// Computes type signature of the intrinsic \p Int.
>From d2e6fb01151b0c52e9d54a0fec6848026e6194f9 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 14 Apr 2026 21:56:15 +0000
Subject: [PATCH 2/4] switch to checking property instead of TTI
---
llvm/include/llvm/Analysis/VectorUtils.h | 3 +--
llvm/lib/Analysis/VectorUtils.cpp | 8 ++------
llvm/lib/Transforms/Scalar/Scalarizer.cpp | 4 ++--
3 files changed, 5 insertions(+), 10 deletions(-)
diff --git a/llvm/include/llvm/Analysis/VectorUtils.h b/llvm/include/llvm/Analysis/VectorUtils.h
index ce94906ee7c00..9f7a606d89306 100644
--- a/llvm/include/llvm/Analysis/VectorUtils.h
+++ b/llvm/include/llvm/Analysis/VectorUtils.h
@@ -146,8 +146,7 @@ LLVM_ABI bool isTriviallyVectorizable(Intrinsic::ID ID);
/// intrinsic is redundant, but we want to implement scalarization of the
/// vector. To prevent the requirement that an intrinsic also implements
/// vectorization we provide this separate function.
-LLVM_ABI bool isTriviallyScalarizable(Intrinsic::ID ID,
- const TargetTransformInfo *TTI);
+LLVM_ABI bool isTriviallyScalarizable(Intrinsic::ID ID);
/// Identifies if the vector form of the intrinsic has a scalar operand.
/// \p TTI is used to consider target specific intrinsics, if no target specific
diff --git a/llvm/lib/Analysis/VectorUtils.cpp b/llvm/lib/Analysis/VectorUtils.cpp
index f7055dbde275b..8b4d6d9652414 100644
--- a/llvm/lib/Analysis/VectorUtils.cpp
+++ b/llvm/lib/Analysis/VectorUtils.cpp
@@ -129,15 +129,11 @@ bool llvm::isTriviallyVectorizable(Intrinsic::ID ID) {
}
}
-bool llvm::isTriviallyScalarizable(Intrinsic::ID ID,
- const TargetTransformInfo *TTI) {
+bool llvm::isTriviallyScalarizable(Intrinsic::ID ID) {
if (isTriviallyVectorizable(ID))
return true;
- if (TTI && Intrinsic::isTargetIntrinsic(ID))
- return TTI->isTargetIntrinsicTriviallyScalarizable(ID);
-
- return false;
+ return Intrinsic::isTriviallyScalarizable(ID);
}
/// Identifies if the vector form of the intrinsic has a scalar operand.
diff --git a/llvm/lib/Transforms/Scalar/Scalarizer.cpp b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
index 0ef8e5790b7f8..006f4c13d045e 100644
--- a/llvm/lib/Transforms/Scalar/Scalarizer.cpp
+++ b/llvm/lib/Transforms/Scalar/Scalarizer.cpp
@@ -711,7 +711,7 @@ bool ScalarizerVisitor::splitCall(CallInst &CI) {
Intrinsic::ID ID = F->getIntrinsicID();
- if (ID == Intrinsic::not_intrinsic || !isTriviallyScalarizable(ID, TTI))
+ if (ID == Intrinsic::not_intrinsic || !isTriviallyScalarizable(ID))
return false;
// unsigned NumElems = VT->getNumElements();
@@ -1083,7 +1083,7 @@ bool ScalarizerVisitor::visitExtractValueInst(ExtractValueInst &EVI) {
if (!F)
return false;
Intrinsic::ID ID = F->getIntrinsicID();
- if (ID == Intrinsic::not_intrinsic || !isTriviallyScalarizable(ID, TTI))
+ if (ID == Intrinsic::not_intrinsic || !isTriviallyScalarizable(ID))
return false;
// Note: Fall through means Operand is a`CallInst` and it is defined in
// `isTriviallyScalarizable`.
>From 708556476c55aaa7f8dd1b295b6492ef292620b8 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 14 Apr 2026 21:57:10 +0000
Subject: [PATCH 3/4] update dx intrinsics to use intrinsic property
---
llvm/include/llvm/IR/IntrinsicsDirectX.td | 74 +++++++++----------
.../DirectX/DirectXTargetTransformInfo.cpp | 46 ------------
2 files changed, 37 insertions(+), 83 deletions(-)
diff --git a/llvm/include/llvm/IR/IntrinsicsDirectX.td b/llvm/include/llvm/IR/IntrinsicsDirectX.td
index 728bf47a17516..13fd0e2dc6255 100644
--- a/llvm/include/llvm/IR/IntrinsicsDirectX.td
+++ b/llvm/include/llvm/IR/IntrinsicsDirectX.td
@@ -175,12 +175,12 @@ def int_dx_resource_casthandle : Intrinsic<[llvm_any_ty], [llvm_any_ty]>;
def int_dx_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
def int_dx_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_any_ty], [IntrNoMem]>;
-def int_dx_asdouble : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [llvm_anyint_ty, LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_asdouble : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [llvm_anyint_ty, LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_uclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_sclamp : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_nclamp : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_cross : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_saturate : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_saturate : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_dot2 : DefaultAttrsIntrinsic<[LLVMMatchType<0>],
[
@@ -222,68 +222,68 @@ def int_dx_dot2add :
def int_dx_dot4add_i8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
def int_dx_dot4add_u8packed : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i32_ty, llvm_i32_ty, llvm_i32_ty], [IntrNoMem]>;
-def int_dx_frac : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_frac : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_degrees : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_dx_isinf : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [llvm_anyfloat_ty], [IntrNoMem]>;
+ [llvm_anyfloat_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_isnan : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>],
- [llvm_anyfloat_ty], [IntrNoMem]>;
+ [llvm_anyfloat_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_legacyf16tof32 : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_float_ty>],
- [llvm_anyint_ty], [IntrNoMem]>;
+ [llvm_anyint_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_legacyf32tof16 : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>],
- [llvm_anyfloat_ty], [IntrNoMem]>;
+ [llvm_anyfloat_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_lerp : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>,LLVMMatchType<0>],
[IntrNoMem]>;
-def int_dx_imad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_imad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_umad : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_normalize : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty], [IntrNoMem]>;
def int_dx_wave_prefix_bit_count : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
-def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
+def int_dx_rsqrt : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_wave_active_countbits : DefaultAttrsIntrinsic<[llvm_i32_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_all_equal : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [llvm_any_ty], [IntrConvergent, IntrNoMem]>;
+def int_dx_wave_all_equal : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i1_ty>], [llvm_any_ty], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_wave_all : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
def int_dx_wave_any : DefaultAttrsIntrinsic<[llvm_i1_ty], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
def int_dx_wave_ballot : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>, LLVMMatchType<0>, LLVMMatchType<0>], [llvm_i1_ty], [IntrConvergent, IntrNoMem]>;
def int_dx_wave_getlaneindex : DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_or : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_xor : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_and : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_max : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_umax : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_min : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_umin : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_sum : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_reduce_usum : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_product : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_uproduct : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
+def int_dx_wave_reduce_or : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_xor : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_and : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_max : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_umax : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_min : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_umin : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_sum : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_reduce_usum : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_product : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_uproduct : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_wave_is_first_lane : DefaultAttrsIntrinsic<[llvm_i1_ty], [], [IntrConvergent]>;
-def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem]>;
+def int_dx_wave_readlane : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>, llvm_i32_ty], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_wave_get_lane_count
: DefaultAttrsIntrinsic<[llvm_i32_ty], [], [IntrConvergent]>;
-def int_dx_wave_prefix_sum : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_prefix_usum : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_prefix_product : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_wave_prefix_uproduct : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_quad_read_across_x : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
-def int_dx_quad_read_across_y : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem]>;
+def int_dx_wave_prefix_sum : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_prefix_usum : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_prefix_product : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_wave_prefix_uproduct : DefaultAttrsIntrinsic<[llvm_anyint_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_quad_read_across_x : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_quad_read_across_y : DefaultAttrsIntrinsic<[llvm_any_ty], [LLVMMatchType<0>], [IntrConvergent, IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_sign : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_any_ty], [IntrNoMem]>;
def int_dx_step : DefaultAttrsIntrinsic<[LLVMMatchType<0>], [llvm_anyfloat_ty, LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_splitdouble : DefaultAttrsIntrinsic<[llvm_anyint_ty, LLVMMatchType<0>],
- [LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem]>;
+ [LLVMScalarOrSameVectorWidth<0, llvm_double_ty>], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_radians : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
def int_dx_discard : DefaultAttrsIntrinsic<[], [llvm_i1_ty], []>;
-def int_dx_ddx_coarse : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_ddy_coarse : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_ddx_fine : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_ddy_fine : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem]>;
-def int_dx_firstbituhigh : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem]>;
-def int_dx_firstbitshigh : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem]>;
-def int_dx_firstbitlow : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem]>;
+def int_dx_ddx_coarse : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_ddy_coarse : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_ddx_fine : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_ddy_fine : DefaultAttrsIntrinsic<[llvm_anyfloat_ty], [LLVMMatchType<0>], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_firstbituhigh : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_firstbitshigh : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
+def int_dx_firstbitlow : DefaultAttrsIntrinsic<[LLVMScalarOrSameVectorWidth<0, llvm_i32_ty>], [llvm_anyint_ty], [IntrNoMem, IntrTriviallyScalarizable]>;
def int_dx_group_memory_barrier
: DefaultAttrsIntrinsic<[], [], [IntrConvergent]>;
diff --git a/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.cpp b/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.cpp
index 2badca6ae9bed..9952038aaf7bd 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.cpp
+++ b/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.cpp
@@ -44,49 +44,3 @@ bool DirectXTTIImpl::isTargetIntrinsicWithOverloadTypeAtArg(Intrinsic::ID ID,
return OpdIdx == -1;
}
}
-
-bool DirectXTTIImpl::isTargetIntrinsicTriviallyScalarizable(
- Intrinsic::ID ID) const {
- switch (ID) {
- case Intrinsic::dx_asdouble:
- case Intrinsic::dx_firstbitlow:
- case Intrinsic::dx_firstbitshigh:
- case Intrinsic::dx_firstbituhigh:
- case Intrinsic::dx_frac:
- case Intrinsic::dx_isinf:
- case Intrinsic::dx_isnan:
- case Intrinsic::dx_legacyf16tof32:
- case Intrinsic::dx_legacyf32tof16:
- case Intrinsic::dx_rsqrt:
- case Intrinsic::dx_saturate:
- case Intrinsic::dx_splitdouble:
- case Intrinsic::dx_wave_all_equal:
- case Intrinsic::dx_wave_readlane:
- case Intrinsic::dx_wave_reduce_or:
- case Intrinsic::dx_wave_reduce_xor:
- case Intrinsic::dx_wave_reduce_and:
- case Intrinsic::dx_wave_reduce_max:
- case Intrinsic::dx_wave_reduce_min:
- case Intrinsic::dx_wave_reduce_sum:
- case Intrinsic::dx_wave_product:
- case Intrinsic::dx_wave_prefix_sum:
- case Intrinsic::dx_wave_prefix_product:
- case Intrinsic::dx_wave_reduce_umax:
- case Intrinsic::dx_wave_reduce_umin:
- case Intrinsic::dx_wave_reduce_usum:
- case Intrinsic::dx_wave_uproduct:
- case Intrinsic::dx_wave_prefix_usum:
- case Intrinsic::dx_wave_prefix_uproduct:
- case Intrinsic::dx_quad_read_across_x:
- case Intrinsic::dx_quad_read_across_y:
- case Intrinsic::dx_imad:
- case Intrinsic::dx_umad:
- case Intrinsic::dx_ddx_coarse:
- case Intrinsic::dx_ddy_coarse:
- case Intrinsic::dx_ddx_fine:
- case Intrinsic::dx_ddy_fine:
- return true;
- default:
- return false;
- }
-}
>From 8887f90ae1f6b1513b38c9b4418d92e077f4acc0 Mon Sep 17 00:00:00 2001
From: Finn Plummer <mail at inbelic.dev>
Date: Tue, 14 Apr 2026 21:57:19 +0000
Subject: [PATCH 4/4] remove dead code
---
llvm/include/llvm/Analysis/TargetTransformInfo.h | 2 --
llvm/include/llvm/Analysis/TargetTransformInfoImpl.h | 4 ----
llvm/include/llvm/CodeGen/BasicTTIImpl.h | 4 ----
llvm/lib/Analysis/TargetTransformInfo.cpp | 5 -----
llvm/lib/Target/DirectX/DirectXTargetTransformInfo.h | 1 -
5 files changed, 16 deletions(-)
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfo.h b/llvm/include/llvm/Analysis/TargetTransformInfo.h
index 3c4f00c0d87b5..963ff652d7e63 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfo.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfo.h
@@ -1039,8 +1039,6 @@ class TargetTransformInfo {
/// convention.
LLVM_ABI bool useFastCCForInternalCall(Function &F) const;
- LLVM_ABI bool isTargetIntrinsicTriviallyScalarizable(Intrinsic::ID ID) const;
-
/// Identifies if the vector form of the intrinsic has a scalar operand.
LLVM_ABI bool isTargetIntrinsicWithScalarOpAtArg(Intrinsic::ID ID,
unsigned ScalarOpdIdx) const;
diff --git a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
index 7eb363c7b4404..2c610fdfbb45d 100644
--- a/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
+++ b/llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
@@ -481,10 +481,6 @@ class TargetTransformInfoImplBase {
virtual bool useFastCCForInternalCall(Function &F) const { return true; }
- virtual bool isTargetIntrinsicTriviallyScalarizable(Intrinsic::ID ID) const {
- return false;
- }
-
virtual bool isTargetIntrinsicWithScalarOpAtArg(Intrinsic::ID ID,
unsigned ScalarOpdIdx) const {
return false;
diff --git a/llvm/include/llvm/CodeGen/BasicTTIImpl.h b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
index aa8f9beacac90..de5ff0084e3e7 100644
--- a/llvm/include/llvm/CodeGen/BasicTTIImpl.h
+++ b/llvm/include/llvm/CodeGen/BasicTTIImpl.h
@@ -931,10 +931,6 @@ class BasicTTIImplBase : public TargetTransformInfoImplCRTPBase<T> {
return Cost;
}
- bool isTargetIntrinsicTriviallyScalarizable(Intrinsic::ID ID) const override {
- return false;
- }
-
bool
isTargetIntrinsicWithScalarOpAtArg(Intrinsic::ID ID,
unsigned ScalarOpdIdx) const override {
diff --git a/llvm/lib/Analysis/TargetTransformInfo.cpp b/llvm/lib/Analysis/TargetTransformInfo.cpp
index 5111593d76a6d..4cbe37ced39ba 100644
--- a/llvm/lib/Analysis/TargetTransformInfo.cpp
+++ b/llvm/lib/Analysis/TargetTransformInfo.cpp
@@ -628,11 +628,6 @@ bool TargetTransformInfo::useFastCCForInternalCall(Function &F) const {
return TTIImpl->useFastCCForInternalCall(F);
}
-bool TargetTransformInfo::isTargetIntrinsicTriviallyScalarizable(
- Intrinsic::ID ID) const {
- return TTIImpl->isTargetIntrinsicTriviallyScalarizable(ID);
-}
-
bool TargetTransformInfo::isTargetIntrinsicWithScalarOpAtArg(
Intrinsic::ID ID, unsigned ScalarOpdIdx) const {
return TTIImpl->isTargetIntrinsicWithScalarOpAtArg(ID, ScalarOpdIdx);
diff --git a/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.h b/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.h
index 4f914f53e2ed7..fdbbc18003419 100644
--- a/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.h
+++ b/llvm/lib/Target/DirectX/DirectXTargetTransformInfo.h
@@ -34,7 +34,6 @@ class DirectXTTIImpl final : public BasicTTIImplBase<DirectXTTIImpl> {
: BaseT(TM, F.getDataLayout()), ST(TM->getSubtargetImpl(F)),
TLI(ST->getTargetLowering()) {}
unsigned getMinVectorRegisterBitWidth() const override { return 32; }
- bool isTargetIntrinsicTriviallyScalarizable(Intrinsic::ID ID) const override;
bool isTargetIntrinsicWithScalarOpAtArg(Intrinsic::ID ID,
unsigned ScalarOpdIdx) const override;
bool isTargetIntrinsicWithOverloadTypeAtArg(Intrinsic::ID ID,
More information about the llvm-commits
mailing list