https://github.com/danbrown-amd updated 
https://github.com/llvm/llvm-project/pull/221105

>From fd03dab0bfc9b9c3acbe02f83850bfa70284c08a Mon Sep 17 00:00:00 2001
From: danbrown-amd <[email protected]>
Date: Thu, 3 Sep 2026 18:46:23 -0600
Subject: [PATCH 1/4] Use icmp-ne instead of truncation on boolean load

Fixes #140824

Assisted-by: Claude Sonnet 4
---
 clang/lib/CodeGen/CGExpr.cpp              | 5 +++--
 clang/lib/Frontend/CompilerInvocation.cpp | 6 ++++++
 clang/test/CodeGenHLSL/strict-bool.hlsl   | 2 +-
 3 files changed, 10 insertions(+), 3 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 019159dd620fda..f5d053e6b67130 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5681,9 +5681,10 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
     Address VecMem = CreateMemTemp(E->getBase()->getType());
     // need to zero extend an hlsl boolean vector to store it back to memory
     QualType Ty = E->getBase()->getType();
-    llvm::Type *LTy = convertTypeForLoadStore(Ty, Vec->getType());
-    if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
+    if (getLangOpts().HLSL && Ty->isExtVectorBoolType()) {
+      llvm::Type *LTy = convertTypeForLoadStore(Ty, Vec->getType());
       Vec = Builder.CreateZExt(Vec, LTy);
+    }
     Builder.CreateStore(Vec, VecMem);
     Base = MakeAddrLValue(VecMem, Ty, AlignmentSource::Decl);
   }
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index c9281c2a6d6b41..0a3a235fbac33c 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -657,6 +657,12 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
       Warnings.insert(Warnings.begin(), "vector-conversion");
     if (!llvm::is_contained(Warnings, "matrix-conversion"))
       Warnings.insert(Warnings.begin(), "matrix-conversion");
+
+    // HLSL booleans in memory are i32; any non-zero value is true.
+    // Use icmp-ne rather than truncation to avoid InstCombine rewriting
+    // trunc i32 to i1 into an illegal wide <N x i1> bitcast (issue #140824).
+    if (!Args.hasArg(OPT_load_bool_from_mem))
+      CodeGenOpts.setLoadBoolFromMem(CodeGenOptions::BoolFromMem::NonZero);
   }
 
   // When these options are used, the compiler is allowed to apply
diff --git a/clang/test/CodeGenHLSL/strict-bool.hlsl 
b/clang/test/CodeGenHLSL/strict-bool.hlsl
index 31867065e77a3b..30bdc02231fa5a 100644
--- a/clang/test/CodeGenHLSL/strict-bool.hlsl
+++ b/clang/test/CodeGenHLSL/strict-bool.hlsl
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O1 
-load-bool-from-mem=truncate -emit-llvm -o - %s | FileCheck %s 
-check-prefixes=CHECK-TRUNCATE
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O1 
-load-bool-from-mem=nonzero -emit-llvm -o - %s | FileCheck %s 
-check-prefixes=CHECK-NONZERO
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O0 -emit-llvm -o - 
%s | FileCheck %s -check-prefixes=CHECK-NONZERO
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O1 -emit-llvm -o - 
%s | FileCheck %s -check-prefixes=CHECK-NONZERO
 
 typedef bool bool8_t __attribute__((ext_vector_type(8)));
 extern bool8_t vec;

>From a54e001a8ec8dc38aaaed2eed75b54af43a15fa8 Mon Sep 17 00:00:00 2001
From: danbrown-amd <[email protected]>
Date: Thu, 8 Oct 2026 16:30:54 -0600
Subject: [PATCH 2/4] Revert test and one source file as per review comments

---
 clang/lib/CodeGen/CGExpr.cpp            | 5 ++---
 clang/test/CodeGenHLSL/strict-bool.hlsl | 2 +-
 2 files changed, 3 insertions(+), 4 deletions(-)

diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index f5d053e6b67130..019159dd620fda 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -5681,10 +5681,9 @@ EmitExtVectorElementExpr(const ExtVectorElementExpr *E) {
     Address VecMem = CreateMemTemp(E->getBase()->getType());
     // need to zero extend an hlsl boolean vector to store it back to memory
     QualType Ty = E->getBase()->getType();
-    if (getLangOpts().HLSL && Ty->isExtVectorBoolType()) {
-      llvm::Type *LTy = convertTypeForLoadStore(Ty, Vec->getType());
+    llvm::Type *LTy = convertTypeForLoadStore(Ty, Vec->getType());
+    if (LTy->getScalarSizeInBits() > Vec->getType()->getScalarSizeInBits())
       Vec = Builder.CreateZExt(Vec, LTy);
-    }
     Builder.CreateStore(Vec, VecMem);
     Base = MakeAddrLValue(VecMem, Ty, AlignmentSource::Decl);
   }
diff --git a/clang/test/CodeGenHLSL/strict-bool.hlsl 
b/clang/test/CodeGenHLSL/strict-bool.hlsl
index 30bdc02231fa5a..31867065e77a3b 100644
--- a/clang/test/CodeGenHLSL/strict-bool.hlsl
+++ b/clang/test/CodeGenHLSL/strict-bool.hlsl
@@ -1,6 +1,6 @@
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O1 
-load-bool-from-mem=truncate -emit-llvm -o - %s | FileCheck %s 
-check-prefixes=CHECK-TRUNCATE
 // RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O1 
-load-bool-from-mem=nonzero -emit-llvm -o - %s | FileCheck %s 
-check-prefixes=CHECK-NONZERO
-// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O1 -emit-llvm -o - 
%s | FileCheck %s -check-prefixes=CHECK-NONZERO
+// RUN: %clang_cc1 -triple dxil-pc-shadermodel6.3-library -O0 -emit-llvm -o - 
%s | FileCheck %s -check-prefixes=CHECK-NONZERO
 
 typedef bool bool8_t __attribute__((ext_vector_type(8)));
 extern bool8_t vec;

>From 3591f213ca47a3e79e4f86de7a5d8e561250d358 Mon Sep 17 00:00:00 2001
From: danbrown-amd <[email protected]>
Date: Tue, 13 Oct 2026 23:10:48 -0600
Subject: [PATCH 3/4] Address additional review comments

---
 clang/include/clang/Basic/DiagnosticFrontendKinds.td | 3 +++
 clang/lib/Driver/ToolChains/HLSL.cpp                 | 1 +
 clang/lib/Frontend/CompilerInvocation.cpp            | 4 ++++
 clang/test/Driver/HLSL/load-bool-from-mem.hlsl       | 3 +++
 4 files changed, 11 insertions(+)
 create mode 100644 clang/test/Driver/HLSL/load-bool-from-mem.hlsl

diff --git a/clang/include/clang/Basic/DiagnosticFrontendKinds.td 
b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
index 66eeb08034bf4b..2281836406e63e 100644
--- a/clang/include/clang/Basic/DiagnosticFrontendKinds.td
+++ b/clang/include/clang/Basic/DiagnosticFrontendKinds.td
@@ -514,6 +514,9 @@ def warn_hlsl_signature_packing_ignored : Warning<
 def warn_hlsl_failed_to_embed_source
     : Warning<"failed to embed source for '%0' into dx.source.contents">,
       InGroup<HLSLDXCCompat>;
+def warn_hlsl_bool_from_mem
+    : Warning<"-load-bool-from-mem=%0 ignored for HLSL (always nonzero)">,
+      InGroup<OptionIgnored>, DefaultWarn;
 
 def err_data_layout_mismatch : Error<"backend data layout '%0' does not match "
                                      "expected target description '%1'">;
diff --git a/clang/lib/Driver/ToolChains/HLSL.cpp 
b/clang/lib/Driver/ToolChains/HLSL.cpp
index b5356f1ec45d33..7b0be0ab1f4020 100644
--- a/clang/lib/Driver/ToolChains/HLSL.cpp
+++ b/clang/lib/Driver/ToolChains/HLSL.cpp
@@ -689,4 +689,5 @@ void HLSLToolChain::addClangWarningOptions(ArgStringList 
&CC1Args) const {
   CC1Args.push_back("-Wconversion");
   CC1Args.push_back("-Wvector-conversion");
   CC1Args.push_back("-Wmatrix-conversion");
+  CC1Args.push_back("-load-bool-from-mem=nonzero");
 }
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 0a3a235fbac33c..49246f7b6d4d04 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -663,6 +663,10 @@ static bool FixupInvocation(CompilerInvocation &Invocation,
     // trunc i32 to i1 into an illegal wide <N x i1> bitcast (issue #140824).
     if (!Args.hasArg(OPT_load_bool_from_mem))
       CodeGenOpts.setLoadBoolFromMem(CodeGenOptions::BoolFromMem::NonZero);
+    else if (CodeGenOpts.getLoadBoolFromMem() !=
+             CodeGenOptions::BoolFromMem::NonZero)
+      Diags.Report(diag::warn_hlsl_bool_from_mem)
+          << Args.getLastArg(OPT_load_bool_from_mem)->getValue();
   }
 
   // When these options are used, the compiler is allowed to apply
diff --git a/clang/test/Driver/HLSL/load-bool-from-mem.hlsl 
b/clang/test/Driver/HLSL/load-bool-from-mem.hlsl
new file mode 100644
index 00000000000000..23ee8cca8b6def
--- /dev/null
+++ b/clang/test/Driver/HLSL/load-bool-from-mem.hlsl
@@ -0,0 +1,3 @@
+// RUN: %clang_dxc -T cs_6_3 -### %s 2>&1 | FileCheck %s
+
+// CHECK: "-load-bool-from-mem=nonzero"

>From 82a1b354fc007b6aad8b9ca3fccb23841cda7648 Mon Sep 17 00:00:00 2001
From: danbrown-amd <[email protected]>
Date: Wed, 14 Oct 2026 21:55:05 -0600
Subject: [PATCH 4/4] Address further review comments

---
 clang/lib/Frontend/CompilerInvocation.cpp    |  8 ++++----
 clang/test/CodeGenHLSL/BoolVector.hlsl       |  3 +++
 clang/test/CodeGenHLSL/bool-vector-load.hlsl | 16 ++++++++++++++++
 3 files changed, 23 insertions(+), 4 deletions(-)
 create mode 100644 clang/test/CodeGenHLSL/bool-vector-load.hlsl

diff --git a/clang/lib/Frontend/CompilerInvocation.cpp 
b/clang/lib/Frontend/CompilerInvocation.cpp
index 49246f7b6d4d04..c44e07533825b3 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -661,12 +661,12 @@ static bool FixupInvocation(CompilerInvocation 
&Invocation,
     // HLSL booleans in memory are i32; any non-zero value is true.
     // Use icmp-ne rather than truncation to avoid InstCombine rewriting
     // trunc i32 to i1 into an illegal wide <N x i1> bitcast (issue #140824).
-    if (!Args.hasArg(OPT_load_bool_from_mem))
-      CodeGenOpts.setLoadBoolFromMem(CodeGenOptions::BoolFromMem::NonZero);
-    else if (CodeGenOpts.getLoadBoolFromMem() !=
-             CodeGenOptions::BoolFromMem::NonZero)
+    if (Args.hasArg(OPT_load_bool_from_mem) &&
+        CodeGenOpts.getLoadBoolFromMem() !=
+        CodeGenOptions::BoolFromMem::NonZero)
       Diags.Report(diag::warn_hlsl_bool_from_mem)
           << Args.getLastArg(OPT_load_bool_from_mem)->getValue();
+    CodeGenOpts.setLoadBoolFromMem(CodeGenOptions::BoolFromMem::NonZero);
   }
 
   // When these options are used, the compiler is allowed to apply
diff --git a/clang/test/CodeGenHLSL/BoolVector.hlsl 
b/clang/test/CodeGenHLSL/BoolVector.hlsl
index 3ee605bf536a7e..41f70038ae8e74 100644
--- a/clang/test/CodeGenHLSL/BoolVector.hlsl
+++ b/clang/test/CodeGenHLSL/BoolVector.hlsl
@@ -1,4 +1,7 @@
 // RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes -o - %s | 
FileCheck %s
+// RUN: %clang_cc1 -finclude-default-header -triple 
dxil-pc-shadermodel6.3-library -emit-llvm -disable-llvm-passes 
-load-bool-from-mem=truncate -o - %s 2>&1 | FileCheck %s 
--check-prefix=CHECK,TRUNCATE
+
+// TRUNCATE: -load-bool-from-mem=truncate ignored for HLSL (always nonzero)
 
 // CHECK: %struct.S = type { <2 x i32>, float }
 // CHECK: [[ConstS:@.*]] = private unnamed_addr constant %struct.S { <2 x i32> 
splat (i32 1), float 1.000000e+00 }, align 1
diff --git a/clang/test/CodeGenHLSL/bool-vector-load.hlsl 
b/clang/test/CodeGenHLSL/bool-vector-load.hlsl
new file mode 100644
index 00000000000000..9f7e8725f0be0b
--- /dev/null
+++ b/clang/test/CodeGenHLSL/bool-vector-load.hlsl
@@ -0,0 +1,16 @@
+// RUN: %clang_dxc -T cs_6_6 %s | FileCheck %s
+
+StructuredBuffer<bool4> In : register(t0);
+RWStructuredBuffer<bool4> Out : register(u1);
+
+// CHECK-LABEL: define {{.*}}main
+// CHECK: [[Load:%.*]] = call {{[^ ]*}} @dx.op.rawBufferLoad.i32(i32 139, 
%dx.types.Handle %{{[^,]*}}, i32 0, i32 12, i8 1, i32 4)
+// CHECK: [[Elem:%.*]] = extractvalue {{.*}} [[BoolVec]], 0
+// CHECK-NEXT: [[Bool:%.*]] = icmp ne i32 [[Elem]], 0
+// CHECK: [[Wide:%.*]] = zext i1 [[Bool]] to i32
+// CHECK: store i32 [[Wide]]
+[numthreads(1,1,1)]
+void main(void) {
+    Out[1].w = In[0].w;
+}
+

_______________________________________________
cfe-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to