[llvm] [X86] Fix a>b being different than b<a on -mattr=+avx2 (PR #195712)
via llvm-commits
llvm-commits at lists.llvm.org
Mon May 4 13:47:21 PDT 2026
https://github.com/thatSteveFan updated https://github.com/llvm/llvm-project/pull/195712
>From 3b850d6dd7dcfd2e163680d317af15bdad517d42 Mon Sep 17 00:00:00 2001
From: thatSteveFan <pnaduthota at google.com>
Date: Sat, 2 May 2026 03:34:54 +0000
Subject: [PATCH 1/2] Fix a>b being different than b<a on -mattr=+avx2
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 7 +++++++
.../CodeGen/X86/vector-unsigned-cmp-fold-load.ll | 12 ++++++++++++
2 files changed, 19 insertions(+)
create mode 100644 llvm/test/CodeGen/X86/vector-unsigned-cmp-fold-load.ll
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 5a1171b2b4ee6..7fa41bf1d1ccd 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -25060,6 +25060,13 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget,
if (ISD::isUnsignedIntSetCC(Cond) &&
(FlipSigns || ISD::isTrueWhenEqual(Cond)) &&
TLI.isOperationLegal(ISD::UMIN, VT)) {
+ // If Op0 is a load and Op1 is not, swap them to allow folding the load
+ // into the min/max operation.
+ if (Op0.getOpcode() == ISD::LOAD && Op1.getOpcode() != ISD::LOAD) {
+ std::swap(Op0, Op1);
+ Cond = ISD::getSetCCSwappedOperands(Cond);
+ }
+
// If we have a constant operand, increment/decrement it and change the
// condition to avoid an invert.
if (Cond == ISD::SETUGT) {
diff --git a/llvm/test/CodeGen/X86/vector-unsigned-cmp-fold-load.ll b/llvm/test/CodeGen/X86/vector-unsigned-cmp-fold-load.ll
new file mode 100644
index 0000000000000..a28b0eee83832
--- /dev/null
+++ b/llvm/test/CodeGen/X86/vector-unsigned-cmp-fold-load.ll
@@ -0,0 +1,12 @@
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s
+
+define <8 x i32> @count_lt1_ir(<8 x i32> %y, <8 x i32>* %p) {
+; CHECK-LABEL: count_lt1_ir:
+; CHECK: # %bb.0:
+; CHECK: vpminud (%{{[a-z0-9]+}}), %ymm{{[0-9]+}}, %ymm{{[0-9]+}}
+; CHECK: retq
+ %x = load <8 x i32>, <8 x i32>* %p
+ %cmp = icmp ult <8 x i32> %x, %y
+ %sext = sext <8 x i1> %cmp to <8 x i32>
+ ret <8 x i32> %sext
+}
>From 2938ce76d3d8653856fad876f8e12f79c951e4bb Mon Sep 17 00:00:00 2001
From: thatSteveFan <pnaduthota at google.com>
Date: Mon, 4 May 2026 20:41:16 +0000
Subject: [PATCH 2/2] Change to mayFoldLoad and add testcase for multi-load
---
llvm/lib/Target/X86/X86ISelLowering.cpp | 2 +-
llvm/test/CodeGen/X86/avx2-icmp-multiuse.ll | 67 +++++++++++++++++++++
2 files changed, 68 insertions(+), 1 deletion(-)
create mode 100644 llvm/test/CodeGen/X86/avx2-icmp-multiuse.ll
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 7fa41bf1d1ccd..be8fe52482b55 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -25062,7 +25062,7 @@ static SDValue LowerVSETCC(SDValue Op, const X86Subtarget &Subtarget,
TLI.isOperationLegal(ISD::UMIN, VT)) {
// If Op0 is a load and Op1 is not, swap them to allow folding the load
// into the min/max operation.
- if (Op0.getOpcode() == ISD::LOAD && Op1.getOpcode() != ISD::LOAD) {
+ if (X86::mayFoldLoad(Op0, Subtarget) && !X86::mayFoldLoad(Op1, Subtarget)) {
std::swap(Op0, Op1);
Cond = ISD::getSetCCSwappedOperands(Cond);
}
diff --git a/llvm/test/CodeGen/X86/avx2-icmp-multiuse.ll b/llvm/test/CodeGen/X86/avx2-icmp-multiuse.ll
new file mode 100644
index 0000000000000..0500e04917987
--- /dev/null
+++ b/llvm/test/CodeGen/X86/avx2-icmp-multiuse.ll
@@ -0,0 +1,67 @@
+; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
+; RUN: llc < %s -mtriple=i686-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,X86
+; RUN: llc < %s -mtriple=x86_64-unknown-unknown -mattr=+avx2 | FileCheck %s --check-prefixes=CHECK,X64
+
+define <8 x i32> @test_lt_multiuse_op0(ptr %ptr1, ptr %ptr2, ptr %external) nounwind {
+; X86-LABEL: test_lt_multiuse_op0:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: vmovdqa (%edx), %ymm0
+; X86-NEXT: vpmaxud (%ecx), %ymm0, %ymm1
+; X86-NEXT: vmovdqa %ymm0, (%eax)
+; X86-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0
+; X86-NEXT: vpbroadcastd {{.*#+}} ymm1 = [1,1,1,1,1,1,1,1]
+; X86-NEXT: vpandn %ymm1, %ymm0, %ymm0
+; X86-NEXT: retl
+;
+; X64-LABEL: test_lt_multiuse_op0:
+; X64: # %bb.0:
+; X64-NEXT: vmovdqa (%rdi), %ymm0
+; X64-NEXT: vpmaxud (%rsi), %ymm0, %ymm1
+; X64-NEXT: vmovdqa %ymm0, (%rdx)
+; X64-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0
+; X64-NEXT: vpbroadcastd {{.*#+}} ymm1 = [1,1,1,1,1,1,1,1]
+; X64-NEXT: vpandn %ymm1, %ymm0, %ymm0
+; X64-NEXT: retq
+ %a = load <8 x i32>, ptr %ptr1, align 32
+ %b = load <8 x i32>, ptr %ptr2, align 32
+ %cmp = icmp ult <8 x i32> %a, %b
+ store <8 x i32> %a, ptr %external, align 32
+ %res = zext <8 x i1> %cmp to <8 x i32>
+ ret <8 x i32> %res
+}
+
+define <8 x i32> @test_lt_multiuse_op1(ptr %ptr1, ptr %ptr2, ptr %external) nounwind {
+; X86-LABEL: test_lt_multiuse_op1:
+; X86: # %bb.0:
+; X86-NEXT: movl {{[0-9]+}}(%esp), %eax
+; X86-NEXT: movl {{[0-9]+}}(%esp), %ecx
+; X86-NEXT: movl {{[0-9]+}}(%esp), %edx
+; X86-NEXT: vmovdqa (%edx), %ymm0
+; X86-NEXT: vpminud (%ecx), %ymm0, %ymm1
+; X86-NEXT: vmovdqa %ymm0, (%eax)
+; X86-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0
+; X86-NEXT: vpbroadcastd {{.*#+}} ymm1 = [1,1,1,1,1,1,1,1]
+; X86-NEXT: vpandn %ymm1, %ymm0, %ymm0
+; X86-NEXT: retl
+;
+; X64-LABEL: test_lt_multiuse_op1:
+; X64: # %bb.0:
+; X64-NEXT: vmovdqa (%rsi), %ymm0
+; X64-NEXT: vpminud (%rdi), %ymm0, %ymm1
+; X64-NEXT: vmovdqa %ymm0, (%rdx)
+; X64-NEXT: vpcmpeqd %ymm1, %ymm0, %ymm0
+; X64-NEXT: vpbroadcastd {{.*#+}} ymm1 = [1,1,1,1,1,1,1,1]
+; X64-NEXT: vpandn %ymm1, %ymm0, %ymm0
+; X64-NEXT: retq
+ %a = load <8 x i32>, ptr %ptr1, align 32
+ %b = load <8 x i32>, ptr %ptr2, align 32
+ %cmp = icmp ult <8 x i32> %a, %b
+ store <8 x i32> %b, ptr %external, align 32
+ %res = zext <8 x i1> %cmp to <8 x i32>
+ ret <8 x i32> %res
+}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
More information about the llvm-commits
mailing list