[llvm] [SelectionDAG] Don't convert sextload to zextload through a multi-use freeze (PR #196700)

Iris Shi via llvm-commits llvm-commits at lists.llvm.org
Sat May 9 00:45:12 PDT 2026


https://github.com/el-ev created https://github.com/llvm/llvm-project/pull/196700

Resolves #196590.



>From 5e7100dbb1ef3ddd06b62756606b3810f69218d9 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Sat, 9 May 2026 15:38:43 +0800
Subject: [PATCH 1/2] test

---
 .../CodeGen/X86/reduce-load-width-freeze.ll   | 28 +++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll b/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll
index 555ea5d069d85..8f9a14e9bdcd7 100644
--- a/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll
+++ b/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll
@@ -354,3 +354,31 @@ define i16 @srl_freeze_load_i64_to_i16(ptr %p) {
   %trunc = trunc i64 %srl to i16
   ret i16 %trunc
 }
+
+ at g6 = global i8 0
+ at g1 = global i16 0
+
+; incorrect sext -> zext
+define i1 @issue196590() {
+; CHECK-LABEL: issue196590:
+; CHECK:       # %bb.0:
+; CHECK-NEXT:    movq g6 at GOTPCREL(%rip), %rax
+; CHECK-NEXT:    movzbl (%rax), %eax
+; CHECK-NEXT:    movq g1 at GOTPCREL(%rip), %rcx
+; CHECK-NEXT:    movw %ax, (%rcx)
+; CHECK-NEXT:    leal (%rax,%rax), %ecx
+; CHECK-NEXT:    cmpl %eax, %ecx
+; CHECK-NEXT:    setg %al
+; CHECK-NEXT:    retq
+  %a = load i8, ptr @g6
+  %zx = zext i8 %a to i16
+  store i16 %zx, ptr @g1
+  %sx = sext i8 %a to i32
+  %b = load i8, ptr @g6
+  %fr = freeze i8 %b
+  %fr16 = sext i8 %fr to i16
+  %add = add i16 %fr16, %fr16
+  %selsx = sext i16 %add to i32
+  %cmp = icmp sgt i32 %selsx, %sx
+  ret i1 %cmp
+}

>From 66aa157305a170eab55f0f4830a2befd328d8909 Mon Sep 17 00:00:00 2001
From: Iris Shi <0.0 at owo.li>
Date: Sat, 9 May 2026 15:42:35 +0800
Subject: [PATCH 2/2] [SelectionDAG] Don't convert sextload to zextload through
 a multi-use freeze

---
 llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp     | 4 +++-
 llvm/test/CodeGen/X86/reduce-load-width-freeze.ll | 9 +++++----
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 5a467a5a5ba53..a5f7a5ae330f0 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -16545,7 +16545,9 @@ SDValue DAGCombiner::reduceLoadWidth(SDNode *N) {
   // the freeze can depend on the full load value. But its still safe to change
   // the extension type from anyext to zext.
   if (FreezeNode && !FreezeNode.hasOneUse() &&
-      (LN0->getMemoryVT().bitsGT(ExtVT) || ExtType != ISD::ZEXTLOAD))
+      (LN0->getMemoryVT().bitsGT(ExtVT) || ExtType != ISD::ZEXTLOAD ||
+       (LN0->getExtensionType() != ISD::EXTLOAD &&
+        LN0->getExtensionType() != ISD::ZEXTLOAD)))
     return SDValue();
 
   auto AdjustBigEndianShift = [&](unsigned ShAmt) {
diff --git a/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll b/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll
index 8f9a14e9bdcd7..8c6f463647fa2 100644
--- a/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll
+++ b/llvm/test/CodeGen/X86/reduce-load-width-freeze.ll
@@ -358,14 +358,15 @@ define i16 @srl_freeze_load_i64_to_i16(ptr %p) {
 @g6 = global i8 0
 @g1 = global i16 0
 
-; incorrect sext -> zext
+; no incorrect sext -> zext
 define i1 @issue196590() {
 ; CHECK-LABEL: issue196590:
 ; CHECK:       # %bb.0:
 ; CHECK-NEXT:    movq g6 at GOTPCREL(%rip), %rax
-; CHECK-NEXT:    movzbl (%rax), %eax
-; CHECK-NEXT:    movq g1 at GOTPCREL(%rip), %rcx
-; CHECK-NEXT:    movw %ax, (%rcx)
+; CHECK-NEXT:    movsbl (%rax), %eax
+; CHECK-NEXT:    movzbl %al, %ecx
+; CHECK-NEXT:    movq g1 at GOTPCREL(%rip), %rdx
+; CHECK-NEXT:    movw %cx, (%rdx)
 ; CHECK-NEXT:    leal (%rax,%rax), %ecx
 ; CHECK-NEXT:    cmpl %eax, %ecx
 ; CHECK-NEXT:    setg %al



More information about the llvm-commits mailing list