[llvm] Test assert zext (PR #172138)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Dec 13 00:09:26 PST 2025
https://github.com/actinks created https://github.com/llvm/llvm-project/pull/172138
None
>From a80b806e05cf32ce5cb0426d08d0d439a14d6432 Mon Sep 17 00:00:00 2001
From: actink <actink at 163.com>
Date: Fri, 12 Dec 2025 23:08:25 +0800
Subject: [PATCH 1/3] [SDAG] fix miss opt: shl nuw + zext adds unnecessary
masking
close: #171750
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 6 ++-
.../X86/fold-int-pow2-with-fmul-or-fdiv.ll | 4 --
llvm/test/CodeGen/X86/known-never-zero.ll | 4 --
llvm/test/CodeGen/X86/known-pow2.ll | 3 +-
llvm/test/CodeGen/X86/pr171750.ll | 47 +++++++++++++++++++
llvm/test/CodeGen/X86/pr89877.ll | 2 -
6 files changed, 52 insertions(+), 14 deletions(-)
create mode 100644 llvm/test/CodeGen/X86/pr171750.ll
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 6a99d4e29b64f..a0212774d8f17 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1673,8 +1673,10 @@ SDValue DAGCombiner::PromoteIntShiftOp(SDValue Op) {
SDLoc DL(Op);
SDValue N1 = Op.getOperand(1);
- SDValue RV =
- DAG.getNode(ISD::TRUNCATE, DL, VT, DAG.getNode(Opc, DL, PVT, N0, N1));
+ SDValue POp = DAG.getNode(Opc, DL, PVT, N0, N1);
+ if (Opc == ISD::SHL && Op->getFlags().hasNoUnsignedWrap())
+ POp = DAG.getNode(ISD::AssertZext, DL, PVT, POp, DAG.getValueType(VT));
+ SDValue RV = DAG.getNode(ISD::TRUNCATE, DL, VT, POp);
if (Replace)
ReplaceLoadWithPromotedLoad(Op.getOperand(0).getNode(), N0.getNode());
diff --git a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
index b655bda68f906..dea6b47a5961a 100644
--- a/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
+++ b/llvm/test/CodeGen/X86/fold-int-pow2-with-fmul-or-fdiv.ll
@@ -1529,7 +1529,6 @@ define half @fdiv_pow_shl_cnt_fail_out_of_bound2(i16 %cnt) nounwind {
; CHECK-SSE-NEXT: movl $1, %eax
; CHECK-SSE-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-SSE-NEXT: shll %cl, %eax
-; CHECK-SSE-NEXT: movzwl %ax, %eax
; CHECK-SSE-NEXT: cvtsi2ss %eax, %xmm0
; CHECK-SSE-NEXT: callq __truncsfhf2 at PLT
; CHECK-SSE-NEXT: callq __extendhfsf2 at PLT
@@ -1547,7 +1546,6 @@ define half @fdiv_pow_shl_cnt_fail_out_of_bound2(i16 %cnt) nounwind {
; CHECK-AVX2-NEXT: movl $1, %eax
; CHECK-AVX2-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-AVX2-NEXT: shll %cl, %eax
-; CHECK-AVX2-NEXT: movzwl %ax, %eax
; CHECK-AVX2-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
; CHECK-AVX2-NEXT: callq __truncsfhf2 at PLT
; CHECK-AVX2-NEXT: callq __extendhfsf2 at PLT
@@ -1563,7 +1561,6 @@ define half @fdiv_pow_shl_cnt_fail_out_of_bound2(i16 %cnt) nounwind {
; CHECK-ONLY-AVX512F-NEXT: movl $1, %eax
; CHECK-ONLY-AVX512F-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-ONLY-AVX512F-NEXT: shll %cl, %eax
-; CHECK-ONLY-AVX512F-NEXT: movzwl %ax, %eax
; CHECK-ONLY-AVX512F-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
; CHECK-ONLY-AVX512F-NEXT: vcvtps2ph $4, %xmm0, %xmm0
; CHECK-ONLY-AVX512F-NEXT: vcvtph2ps %xmm0, %xmm0
@@ -1576,7 +1573,6 @@ define half @fdiv_pow_shl_cnt_fail_out_of_bound2(i16 %cnt) nounwind {
; CHECK-SKX: # %bb.0:
; CHECK-SKX-NEXT: movl $1, %eax
; CHECK-SKX-NEXT: shlxl %edi, %eax, %eax
-; CHECK-SKX-NEXT: movzwl %ax, %eax
; CHECK-SKX-NEXT: vcvtsi2ss %eax, %xmm15, %xmm0
; CHECK-SKX-NEXT: vcvtps2ph $4, %xmm0, %xmm0
; CHECK-SKX-NEXT: vcvtph2ps %xmm0, %xmm0
diff --git a/llvm/test/CodeGen/X86/known-never-zero.ll b/llvm/test/CodeGen/X86/known-never-zero.ll
index 63336ffa7c6c8..758ebc6177f14 100644
--- a/llvm/test/CodeGen/X86/known-never-zero.ll
+++ b/llvm/test/CodeGen/X86/known-never-zero.ll
@@ -1318,7 +1318,6 @@ define i32 @zext_known_nonzero(i16 %xx) {
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl $256, %eax # imm = 0x100
; X86-NEXT: shll %cl, %eax
-; X86-NEXT: movzwl %ax, %eax
; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
@@ -1328,7 +1327,6 @@ define i32 @zext_known_nonzero(i16 %xx) {
; X64-NEXT: movl $256, %eax # imm = 0x100
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shll %cl, %eax
-; X64-NEXT: movzwl %ax, %eax
; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x = shl nuw nsw i16 256, %xx
@@ -1363,7 +1361,6 @@ define i32 @sext_known_nonzero(i16 %xx) {
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl $256, %eax # imm = 0x100
; X86-NEXT: shll %cl, %eax
-; X86-NEXT: movzwl %ax, %eax
; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
@@ -1373,7 +1370,6 @@ define i32 @sext_known_nonzero(i16 %xx) {
; X64-NEXT: movl $256, %eax # imm = 0x100
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shll %cl, %eax
-; X64-NEXT: movzwl %ax, %eax
; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x = shl nuw nsw i16 256, %xx
diff --git a/llvm/test/CodeGen/X86/known-pow2.ll b/llvm/test/CodeGen/X86/known-pow2.ll
index 019bca7e53b4c..09ceaf8eca3ac 100644
--- a/llvm/test/CodeGen/X86/known-pow2.ll
+++ b/llvm/test/CodeGen/X86/known-pow2.ll
@@ -847,8 +847,7 @@ define i1 @pow2_though_zext(i32 %x, i16 %y) {
; CHECK-NEXT: movl $4, %eax
; CHECK-NEXT: # kill: def $cl killed $cl killed $ecx
; CHECK-NEXT: shll %cl, %eax
-; CHECK-NEXT: andl %edi, %eax
-; CHECK-NEXT: testl $65535, %eax # imm = 0xFFFF
+; CHECK-NEXT: testl %eax, %edi
; CHECK-NEXT: setne %al
; CHECK-NEXT: retq
%dd = shl nuw nsw i16 4, %y
diff --git a/llvm/test/CodeGen/X86/pr171750.ll b/llvm/test/CodeGen/X86/pr171750.ll
new file mode 100644
index 0000000000000..b70536ee215d3
--- /dev/null
+++ b/llvm/test/CodeGen/X86/pr171750.ll
@@ -0,0 +1,47 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=X64
+
+define i32 @_Z1ft(i16 zeroext %0) {
+; X86-LABEL: _Z1ft:
+; X86: # %bb.0: # %entry
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: shll $3, %eax
+; X86-NEXT: retl
+;
+; X64-LABEL: _Z1ft:
+; X64: # %bb.0: # %entry
+; X64-NEXT: # kill: def $edi killed $edi def $rdi
+; X64-NEXT: leal (,%rdi,8), %eax
+; X64-NEXT: retq
+entry:
+ %3 = shl nuw i16 %0, 3
+ %4 = zext i16 %3 to i32
+ ret i32 %4
+}
+
+define i32 @_Z1gt(i16 zeroext %x) {
+; X86-LABEL: _Z1gt:
+; X86: # %bb.0: # %entry
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: leal (,%eax,8), %ecx
+; X86-NEXT: shll $16, %eax
+; X86-NEXT: orl %ecx, %eax
+; X86-NEXT: retl
+;
+; X64-LABEL: _Z1gt:
+; X64: # %bb.0: # %entry
+; X64-NEXT: # kill: def $edi killed $edi def $rdi
+; X64-NEXT: leal (,%rdi,8), %eax
+; X64-NEXT: shll $16, %edi
+; X64-NEXT: orl %edi, %eax
+; X64-NEXT: retq
+entry:
+ %conv = zext nneg i16 %x to i32
+ %shl = shl nuw i16 %x, 3
+ %conv3 = zext i16 %shl to i32
+ %shl5 = shl nuw nsw i32 %conv, 16
+ %or = or disjoint i32 %shl5, %conv3
+ ret i32 %or
+}
+
diff --git a/llvm/test/CodeGen/X86/pr89877.ll b/llvm/test/CodeGen/X86/pr89877.ll
index a40ad8f941278..eeb10edb1002f 100644
--- a/llvm/test/CodeGen/X86/pr89877.ll
+++ b/llvm/test/CodeGen/X86/pr89877.ll
@@ -86,7 +86,6 @@ define i32 @sext_known_nonzero_nuw_nsw(i16 %xx) {
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl $256, %eax # imm = 0x100
; X86-NEXT: shll %cl, %eax
-; X86-NEXT: movzwl %ax, %eax
; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
@@ -96,7 +95,6 @@ define i32 @sext_known_nonzero_nuw_nsw(i16 %xx) {
; X64-NEXT: movl $256, %eax # imm = 0x100
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shll %cl, %eax
-; X64-NEXT: movzwl %ax, %eax
; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x = shl nuw nsw i16 256, %xx
>From dadbde145a39e14dbb2b5ec870fe99b73e3f97cb Mon Sep 17 00:00:00 2001
From: actink <actink at 163.com>
Date: Sat, 13 Dec 2025 11:49:43 +0800
Subject: [PATCH 2/3] fixup shl's promote, add trunc flags
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 +++++++++++++------
.../lib/CodeGen/SelectionDAG/SelectionDAG.cpp | 3 +++
.../CodeGen/X86/{pr171750.ll => pr172046.ll} | 14 +++++++------
llvm/test/CodeGen/X86/pr89877.ll | 2 --
4 files changed, 25 insertions(+), 14 deletions(-)
rename llvm/test/CodeGen/X86/{pr171750.ll => pr172046.ll} (72%)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index a0212774d8f17..666b52be42b72 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1659,24 +1659,32 @@ SDValue DAGCombiner::PromoteIntShiftOp(SDValue Op) {
LLVM_DEBUG(dbgs() << "\nPromoting "; Op.dump(&DAG));
+ SDNodeFlags Flags;
bool Replace = false;
SDValue N0 = Op.getOperand(0);
if (Opc == ISD::SRA)
N0 = SExtPromoteOperand(N0, PVT);
else if (Opc == ISD::SRL)
N0 = ZExtPromoteOperand(N0, PVT);
- else
- N0 = PromoteOperand(N0, PVT, Replace);
+ else {
+ if (Op->getFlags().hasNoUnsignedWrap()) {
+ Flags = SDNodeFlags::NoUnsignedWrap;
+ N0 = ZExtPromoteOperand(N0, PVT);
+ } else if (Op->getFlags().hasNoSignedWrap()) {
+ Flags = SDNodeFlags::NoSignedWrap;
+ N0 = SExtPromoteOperand(N0, PVT);
+ } else
+ N0 = PromoteOperand(N0, PVT, Replace);
+ }
if (!N0.getNode())
return SDValue();
SDLoc DL(Op);
SDValue N1 = Op.getOperand(1);
- SDValue POp = DAG.getNode(Opc, DL, PVT, N0, N1);
- if (Opc == ISD::SHL && Op->getFlags().hasNoUnsignedWrap())
- POp = DAG.getNode(ISD::AssertZext, DL, PVT, POp, DAG.getValueType(VT));
- SDValue RV = DAG.getNode(ISD::TRUNCATE, DL, VT, POp);
+
+ SDValue RV = DAG.getNode(ISD::TRUNCATE, DL, VT,
+ DAG.getNode(Opc, DL, PVT, N0, N1), Flags);
if (Replace)
ReplaceLoadWithPromotedLoad(Op.getOperand(0).getNode(), N0.getNode());
diff --git a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
index cbe3236eb80d9..7795a004d658d 100644
--- a/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
@@ -1572,6 +1572,9 @@ SDValue SelectionDAG::getZeroExtendInReg(SDValue Op, const SDLoc &DL, EVT VT) {
assert(VT.bitsLE(OpVT) && "Not extending!");
if (OpVT == VT)
return Op;
+ if (Op.getOpcode() == ISD::AssertZext &&
+ cast<VTSDNode>(Op.getOperand(1))->getVT().bitsLE(VT))
+ return Op;
APInt Imm = APInt::getLowBitsSet(OpVT.getScalarSizeInBits(),
VT.getScalarSizeInBits());
return getNode(ISD::AND, DL, OpVT, Op, getConstant(Imm, DL, OpVT));
diff --git a/llvm/test/CodeGen/X86/pr171750.ll b/llvm/test/CodeGen/X86/pr172046.ll
similarity index 72%
rename from llvm/test/CodeGen/X86/pr171750.ll
rename to llvm/test/CodeGen/X86/pr172046.ll
index b70536ee215d3..df8c82adb3a59 100644
--- a/llvm/test/CodeGen/X86/pr171750.ll
+++ b/llvm/test/CodeGen/X86/pr172046.ll
@@ -1,12 +1,13 @@
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 3
-; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+sse2 | FileCheck %s --check-prefixes=X86
-; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx | FileCheck %s --check-prefixes=X64
+; RUN: llc < %s -mtriple=i686-unknown-unknown | FileCheck %s --check-prefixes=X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown | FileCheck %s --check-prefixes=X64
define i32 @_Z1ft(i16 zeroext %0) {
; X86-LABEL: _Z1ft:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
; X86-NEXT: shll $3, %eax
+; X86-NEXT: movzwl %ax, %eax
; X86-NEXT: retl
;
; X64-LABEL: _Z1ft:
@@ -24,17 +25,18 @@ define i32 @_Z1gt(i16 zeroext %x) {
; X86-LABEL: _Z1gt:
; X86: # %bb.0: # %entry
; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
-; X86-NEXT: leal (,%eax,8), %ecx
+; X86-NEXT: movl %eax, %ecx
+; X86-NEXT: andl $8191, %ecx # imm = 0x1FFF
; X86-NEXT: shll $16, %eax
-; X86-NEXT: orl %ecx, %eax
+; X86-NEXT: leal (%eax,%ecx,8), %eax
; X86-NEXT: retl
;
; X64-LABEL: _Z1gt:
; X64: # %bb.0: # %entry
; X64-NEXT: # kill: def $edi killed $edi def $rdi
-; X64-NEXT: leal (,%rdi,8), %eax
+; X64-NEXT: movl %edi, %eax
; X64-NEXT: shll $16, %edi
-; X64-NEXT: orl %edi, %eax
+; X64-NEXT: leal (%rdi,%rax,8), %eax
; X64-NEXT: retq
entry:
%conv = zext nneg i16 %x to i32
diff --git a/llvm/test/CodeGen/X86/pr89877.ll b/llvm/test/CodeGen/X86/pr89877.ll
index eeb10edb1002f..ed85e7fe9fb60 100644
--- a/llvm/test/CodeGen/X86/pr89877.ll
+++ b/llvm/test/CodeGen/X86/pr89877.ll
@@ -61,7 +61,6 @@ define i32 @sext_known_nonzero_nsw(i16 %xx) {
; X86-NEXT: movzbl {{[0-9]+}}(%esp), %ecx
; X86-NEXT: movl $256, %eax # imm = 0x100
; X86-NEXT: shll %cl, %eax
-; X86-NEXT: movzwl %ax, %eax
; X86-NEXT: rep bsfl %eax, %eax
; X86-NEXT: retl
;
@@ -71,7 +70,6 @@ define i32 @sext_known_nonzero_nsw(i16 %xx) {
; X64-NEXT: movl $256, %eax # imm = 0x100
; X64-NEXT: # kill: def $cl killed $cl killed $ecx
; X64-NEXT: shll %cl, %eax
-; X64-NEXT: movzwl %ax, %eax
; X64-NEXT: rep bsfl %eax, %eax
; X64-NEXT: retq
%x = shl nsw i16 256, %xx
>From 04ad5874467c469de77c7a4fa4ffc36b85b17ab0 Mon Sep 17 00:00:00 2001
From: actink <actink at 163.com>
Date: Sat, 13 Dec 2025 16:08:30 +0800
Subject: [PATCH 3/3] test assert vs trunc flags
---
llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp | 20 ++++++++++---------
1 file changed, 11 insertions(+), 9 deletions(-)
diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 666b52be42b72..e0998cfd096ee 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -1659,7 +1659,6 @@ SDValue DAGCombiner::PromoteIntShiftOp(SDValue Op) {
LLVM_DEBUG(dbgs() << "\nPromoting "; Op.dump(&DAG));
- SDNodeFlags Flags;
bool Replace = false;
SDValue N0 = Op.getOperand(0);
if (Opc == ISD::SRA)
@@ -1667,13 +1666,11 @@ SDValue DAGCombiner::PromoteIntShiftOp(SDValue Op) {
else if (Opc == ISD::SRL)
N0 = ZExtPromoteOperand(N0, PVT);
else {
- if (Op->getFlags().hasNoUnsignedWrap()) {
- Flags = SDNodeFlags::NoUnsignedWrap;
+ if (Op->getFlags().hasNoUnsignedWrap())
N0 = ZExtPromoteOperand(N0, PVT);
- } else if (Op->getFlags().hasNoSignedWrap()) {
- Flags = SDNodeFlags::NoSignedWrap;
+ else if (Op->getFlags().hasNoSignedWrap())
N0 = SExtPromoteOperand(N0, PVT);
- } else
+ else
N0 = PromoteOperand(N0, PVT, Replace);
}
@@ -1682,9 +1679,14 @@ SDValue DAGCombiner::PromoteIntShiftOp(SDValue Op) {
SDLoc DL(Op);
SDValue N1 = Op.getOperand(1);
-
- SDValue RV = DAG.getNode(ISD::TRUNCATE, DL, VT,
- DAG.getNode(Opc, DL, PVT, N0, N1), Flags);
+ SDValue POp = DAG.getNode(Opc, DL, PVT, N0, N1);
+ if (Opc == ISD::SRL ||
+ (Opc == ISD::SHL && Op->getFlags().hasNoUnsignedWrap()))
+ POp = DAG.getNode(ISD::AssertZext, DL, PVT, POp, DAG.getValueType(VT));
+ else if (Opc == ISD::SRA ||
+ (Opc == ISD::SHL && Op->getFlags().hasNoSignedWrap()))
+ POp = DAG.getNode(ISD::AssertSext, DL, PVT, POp, DAG.getValueType(VT));
+ SDValue RV = DAG.getNode(ISD::TRUNCATE, DL, VT, POp);
if (Replace)
ReplaceLoadWithPromotedLoad(Op.getOperand(0).getNode(), N0.getNode());
More information about the llvm-commits
mailing list