https://github.com/PlutoDog95 created
https://github.com/llvm/llvm-project/pull/196609
Fix an assertion failure in AMDGPULateCodeGenPrepare caused by
invalid bitcasts involving vectors with non-byte-aligned integer
element types such as `<3 x i31>`.
The live register optimization attempts to repack vectors through
bitcasts, but these transformations are not valid for odd-width
element types.
Skip the optimization for vector types whose element widths are
not byte aligned and gracefully bail out when conversion is not
possible.
Add a regression test for the crash.
Reproducer:
```llvm
define void @repro(ptr %p, <3 x i1> %mask) {
%x = call <3 x i31> @llvm.masked.load.v3i31.p0(
ptr %p, <3 x i1> %mask, <3 x i31> zeroinitializer)
call void @llvm.masked.store.v3i31.p0(
<3 x i31> %x, ptr null, <3 x i1> %mask)
ret void
}
```
Fixes #196582
>From a488e1500568f16ad796e1b331c402f6d0dd7190 Mon Sep 17 00:00:00 2001
From: Vineet Agarwal <[email protected]>
Date: Thu, 7 May 2026 19:29:58 +0530
Subject: [PATCH 1/3] [analyzer] Suppress EnumCastOutOfRange diagnostics in
system headers
Suppress EnumCastOutOfRange warnings emitted from system headers.
The checker already receives locations correctly classified as system
headers by SourceManager, but it did not suppress diagnostics for them.
This caused warnings to be emitted from libraries included through
-isystem, such as Boost.Regex.
Add a system-header guard in reportWarning() and add a regression test.
Signed-off-by: Vineet Agarwal <[email protected]>
---
.../Checkers/EnumCastOutOfRangeChecker.cpp | 10 +++++++---
clang/test/Analysis/Inputs/enum-system-header.h | 8 ++++++++
.../enum-cast-out-of-range-system-header.cpp | 12 ++++++++++++
3 files changed, 27 insertions(+), 3 deletions(-)
create mode 100644 clang/test/Analysis/Inputs/enum-system-header.h
create mode 100644 clang/test/Analysis/enum-cast-out-of-range-system-header.cpp
diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
index 76a1470aaac44..32a73a1d5c44f 100644
--- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -85,8 +85,13 @@ void EnumCastOutOfRangeChecker::reportWarning(CheckerContext
&C,
const CastExpr *CE,
const EnumDecl *E) const {
assert(E && "valid EnumDecl* is expected");
- if (const ExplodedNode *N = C.generateNonFatalErrorNode()) {
- std::string ValueStr = "", NameStr = "the enum";
+ auto &SM = C.getSourceManager();
+
+ if (SM.isInSystemHeader(CE->getExprLoc()))
+ return;
+
+ if (const ExplodedNode *N = C.generateNonFatalErrorNode()) {
+ std::string ValueStr = "", NameStr = "the enum";
// Try to add details to the message:
const auto ConcreteValue =
@@ -101,7 +106,6 @@ void
EnumCastOutOfRangeChecker::reportWarning(CheckerContext &C,
std::string Msg = formatv("The value{0} provided to the cast expression is
"
"not in the valid range of values for {1}",
ValueStr, NameStr);
-
auto BR = std::make_unique<PathSensitiveBugReport>(EnumValueCastOutOfRange,
Msg, N);
bugreporter::trackExpressionValue(N, CE->getSubExpr(), *BR);
diff --git a/clang/test/Analysis/Inputs/enum-system-header.h
b/clang/test/Analysis/Inputs/enum-system-header.h
new file mode 100644
index 0000000000000..53c6bdac24093
--- /dev/null
+++ b/clang/test/Analysis/Inputs/enum-system-header.h
@@ -0,0 +1,8 @@
+enum MyEnum {
+ A = 1,
+ B = 2
+};
+
+static inline MyEnum bad_cast(int x) {
+ return (MyEnum)x;
+}
diff --git a/clang/test/Analysis/enum-cast-out-of-range-system-header.cpp
b/clang/test/Analysis/enum-cast-out-of-range-system-header.cpp
new file mode 100644
index 0000000000000..073cde677bcd1
--- /dev/null
+++ b/clang/test/Analysis/enum-cast-out-of-range-system-header.cpp
@@ -0,0 +1,12 @@
+// RUN: %clang_analyze_cc1 \
+// RUN: -analyzer-checker=core,optin.core.EnumCastOutOfRange \
+// RUN: -isystem %S/Inputs \
+// RUN: -verify %s
+
+#include "enum-system-header.h"
+
+void test() {
+ bad_cast(100);
+}
+
+// expected-no-diagnostics
>From 22dddcd7360ab0ad47a3b8342fb863479d345a9c Mon Sep 17 00:00:00 2001
From: Vineet Agarwal <[email protected]>
Date: Fri, 8 May 2026 22:56:40 +0530
Subject: [PATCH 2/3] [clang] Suppress -Wunneeded-internal-declaration for
referenced constexpr functions
Referenced constexpr functions used during constant evaluation may not
be odr-used and therefore do not require emission, but they are still
semantically necessary.
Suppress -Wunneeded-internal-declaration for referenced constexpr
functions, analogous to the existing handling for variables usable in
constant expressions.
Add a regression test for constexpr function usage in a dependent return
type.
---
clang/lib/Sema/Sema.cpp | 5 ++++
.../warn-unused-constexpr-function.cpp | 24 +++++++++++++++++++
2 files changed, 29 insertions(+)
create mode 100644 clang/test/SemaCXX/warn-unused-constexpr-function.cpp
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 8a68f2f19bf3d..9c8a84668454a 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -891,6 +891,11 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const
DeclaratorDecl *D) {
return true;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // If a constexpr function is referenced for constant evaluation,
+ // don't warn even if it is not odr-used.
+ if (FD->isReferenced() && FD->isConstexpr())
+ return true;
+
// If this is a function template and none of its specializations is used,
// we should warn.
if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
diff --git a/clang/test/SemaCXX/warn-unused-constexpr-function.cpp
b/clang/test/SemaCXX/warn-unused-constexpr-function.cpp
new file mode 100644
index 0000000000000..329cfe954c1a6
--- /dev/null
+++ b/clang/test/SemaCXX/warn-unused-constexpr-function.cpp
@@ -0,0 +1,24 @@
+// RUN: %clang_cc1 -std=c++14 -Wunused-function -fsyntax-only %s
+
+static constexpr bool returnInt(int) { return true; }
+
+template <bool B>
+struct select;
+
+template <>
+struct select<true> {
+ using type = int;
+};
+
+template <>
+struct select<false> {
+ using type = float;
+};
+
+template <typename T>
+typename select<returnInt(T{})>::type make() {
+ return T{};
+}
+
+int makeInt() { return make<int>(); }
+float makeFloat() { return make<float>(); }
>From f39733f99f62a7efea622017c903ba1e2839777c Mon Sep 17 00:00:00 2001
From: Vineet Agarwal <[email protected]>
Date: Sat, 9 May 2026 00:22:25 +0530
Subject: [PATCH 3/3] [AMDGPU] Avoid invalid bitcasts for odd-width vector
types
AMDGPU late codegen prepare may attempt to create invalid
bitcasts for vectors with non-byte-aligned integer element
types such as `<3 x i31>`.
Skip the live register optimization for vector types whose
element bit widths are not byte aligned.
Add a regression test for the assertion crash.
---
.../AMDGPU/AMDGPULateCodeGenPrepare.cpp | 5 ++++-
.../AMDGPU/odd-vector-bitcast-crash.ll | 19 +++++++++++++++++++
2 files changed, 23 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/AMDGPU/odd-vector-bitcast-crash.ll
diff --git a/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
b/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
index 63e265612cbf7..f9cd8c9a68139 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPULateCodeGenPrepare.cpp
@@ -250,6 +250,8 @@ Type *LiveRegOptimizer::calculateConvertType(Type
*OriginalType) {
Value *LiveRegOptimizer::convertToOptType(Instruction *V,
BasicBlock::iterator &InsertPt) {
FixedVectorType *VTy = cast<FixedVectorType>(V->getType());
+ if (VTy->getScalarSizeInBits() % 8 != 0)
+ return nullptr;
Type *NewTy = calculateConvertType(V->getType());
TypeSize OriginalSize = DL.getTypeSizeInBits(VTy);
@@ -382,7 +384,8 @@ bool LiveRegOptimizer::optimizeLiveType(
if (!ValMap.contains(D)) {
BasicBlock::iterator InsertPt = std::next(D->getIterator());
Value *ConvertVal = convertToOptType(D, InsertPt);
- assert(ConvertVal);
+ if (!ConvertVal)
+ return false;
ValMap[D] = ConvertVal;
}
}
diff --git a/llvm/test/CodeGen/AMDGPU/odd-vector-bitcast-crash.ll
b/llvm/test/CodeGen/AMDGPU/odd-vector-bitcast-crash.ll
new file mode 100644
index 0000000000000..030c2fd9d506a
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/odd-vector-bitcast-crash.ll
@@ -0,0 +1,19 @@
+; RUN: llc -mtriple=amdgcn-amd-amdhsa -mcpu=gfx1100 -O2 %s -o /dev/null
+
+target triple = "amdgcn-amd-amdhsa"
+
+define void @repro(ptr %p, <3 x i1> %mask) {
+ %x = call <3 x i31> @llvm.masked.load.v3i31.p0(
+ ptr %p, <3 x i1> %mask, <3 x i31> zeroinitializer)
+
+ call void @llvm.masked.store.v3i31.p0(
+ <3 x i31> %x, ptr null, <3 x i1> %mask)
+
+ ret void
+}
+
+declare <3 x i31> @llvm.masked.load.v3i31.p0(
+ ptr, <3 x i1>, <3 x i31>)
+
+declare void @llvm.masked.store.v3i31.p0(
+ <3 x i31>, ptr, <3 x i1>)
_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits