[llvm] [SLP][NFC]Add tests for interchange compares, NFC (PR #218169)
Alexey Bataev via llvm-commits
llvm-commits at lists.llvm.org
Sat Aug 22 16:14:24 PDT 2026
https://github.com/alexey-bataev created https://github.com/llvm/llvm-project/pull/218169
None
>From b885f30f9a68a80a5d83026b0de558f830dcbf73 Mon Sep 17 00:00:00 2001
From: Alexey Bataev <a.bataev at outlook.com>
Date: Sat, 22 Aug 2026 16:14:12 -0700
Subject: [PATCH] =?UTF-8?q?[=F0=9D=98=80=F0=9D=97=BD=F0=9D=97=BF]=20initia?=
=?UTF-8?q?l=20version?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Created using spr 1.3.7
---
.../X86/interchangeable-cmp-predicates.ll | 359 ++++++++++++++++++
1 file changed, 359 insertions(+)
create mode 100644 llvm/test/Transforms/SLPVectorizer/X86/interchangeable-cmp-predicates.ll
diff --git a/llvm/test/Transforms/SLPVectorizer/X86/interchangeable-cmp-predicates.ll b/llvm/test/Transforms/SLPVectorizer/X86/interchangeable-cmp-predicates.ll
new file mode 100644
index 0000000000000..51156bc66d2c3
--- /dev/null
+++ b/llvm/test/Transforms/SLPVectorizer/X86/interchangeable-cmp-predicates.ll
@@ -0,0 +1,359 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6
+; RUN: opt < %s -passes=slp-vectorizer -S -mtriple=x86_64-unknown-linux-gnu | FileCheck %s
+
+; InstCombine canonicalizes boundary range comparisons to eq/ne (e.g.
+; x <u 1 becomes x == 0). Such lanes are interchangeable with the rest of
+; the bundle by adjusting the compared constant.
+
+define <8 x i1> @eq_ult(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @eq_ult(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 0, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP6:%.*]] = insertelement <8 x i16> <i16 poison, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ult <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP4]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP3]]
+;
+ %c1 = icmp eq i16 %x, 0
+ %c2 = icmp ult i16 %x, 2
+ %c3 = icmp ult i16 %x, 3
+ %c4 = icmp ult i16 %x, 4
+ %c5 = icmp ult i16 %x, 5
+ %c6 = icmp ult i16 %x, 6
+ %c7 = icmp ult i16 %x, 7
+ %c8 = icmp ult i16 %x, 8
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+define <8 x i1> @ne_ugt(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @ne_ugt(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 0, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP6:%.*]] = insertelement <8 x i16> <i16 poison, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ugt <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP4]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP3]]
+;
+ %c1 = icmp ne i16 %x, 0
+ %c2 = icmp ugt i16 %x, 1
+ %c3 = icmp ugt i16 %x, 2
+ %c4 = icmp ugt i16 %x, 3
+ %c5 = icmp ugt i16 %x, 4
+ %c6 = icmp ugt i16 %x, 5
+ %c7 = icmp ugt i16 %x, 6
+ %c8 = icmp ugt i16 %x, 7
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+define <8 x i1> @eq_slt_signed_mins(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @eq_slt_signed_mins(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 -32768, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP6:%.*]] = insertelement <8 x i16> <i16 poison, i16 -32766, i16 -32765, i16 -32764, i16 -32763, i16 -32762, i16 -32761, i16 -32760>, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp slt <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP4]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP3]]
+;
+ %c1 = icmp eq i16 %x, -32768
+ %c2 = icmp slt i16 %x, -32766
+ %c3 = icmp slt i16 %x, -32765
+ %c4 = icmp slt i16 %x, -32764
+ %c5 = icmp slt i16 %x, -32763
+ %c6 = icmp slt i16 %x, -32762
+ %c7 = icmp slt i16 %x, -32761
+ %c8 = icmp slt i16 %x, -32760
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+define <8 x i1> @ne_sle_signed_maxs(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @ne_sle_signed_maxs(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 32767, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP6:%.*]] = insertelement <8 x i16> <i16 poison, i16 32765, i16 32764, i16 32763, i16 32762, i16 32761, i16 32760, i16 32759>, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp sle <8 x i16> [[TMP2]], [[TMP6]]
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP4]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP3]]
+;
+ %c1 = icmp ne i16 %x, 32767
+ %c2 = icmp sle i16 %x, 32765
+ %c3 = icmp sle i16 %x, 32764
+ %c4 = icmp sle i16 %x, 32763
+ %c5 = icmp sle i16 %x, 32762
+ %c6 = icmp sle i16 %x, 32761
+ %c7 = icmp sle i16 %x, 32760
+ %c8 = icmp sle i16 %x, 32759
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+define <8 x i1> @ule_ult(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @ule_ult(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ule <8 x i16> [[TMP2]], <i16 0, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ult <8 x i16> [[TMP2]], <i16 0, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[TMP5]], <8 x i1> [[TMP4]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP3]]
+;
+ %c1 = icmp ule i16 %x, 0
+ %c2 = icmp ult i16 %x, 2
+ %c3 = icmp ult i16 %x, 3
+ %c4 = icmp ult i16 %x, 4
+ %c5 = icmp ult i16 %x, 5
+ %c6 = icmp ult i16 %x, 6
+ %c7 = icmp ult i16 %x, 7
+ %c8 = icmp ult i16 %x, 8
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+; Non-boundary constant: x == 5 is not interchangeable with x <u C.
+define <8 x i1> @neg_eq_nonboundary(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @neg_eq_nonboundary(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> <i16 5, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> <i32 0, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP3:%.*]] = insertelement <8 x i16> <i16 poison, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7, i16 8>, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP4:%.*]] = icmp eq <8 x i16> [[TMP2]], [[TMP3]]
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ult <8 x i16> [[TMP2]], [[TMP3]]
+; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <8 x i1> [[TMP4]], <8 x i1> [[TMP5]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP6]]
+;
+ %c1 = icmp eq i16 %x, 5
+ %c2 = icmp ult i16 %x, 2
+ %c3 = icmp ult i16 %x, 3
+ %c4 = icmp ult i16 %x, 4
+ %c5 = icmp ult i16 %x, 5
+ %c6 = icmp ult i16 %x, 6
+ %c7 = icmp ult i16 %x, 7
+ %c8 = icmp ult i16 %x, 8
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+; eq and ne are complements, not interchangeable.
+define <8 x i1> @neg_eq_ne(i16 %x) {
+; CHECK-LABEL: define <8 x i1> @neg_eq_ne(
+; CHECK-SAME: i16 [[X:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <8 x i16> poison, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <8 x i16> [[TMP1]], <8 x i16> poison, <8 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq <8 x i16> [[TMP2]], <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>
+; CHECK-NEXT: [[TMP4:%.*]] = icmp ne <8 x i16> [[TMP2]], <i16 0, i16 1, i16 2, i16 3, i16 4, i16 5, i16 6, i16 7>
+; CHECK-NEXT: [[TMP5:%.*]] = shufflevector <8 x i1> [[TMP3]], <8 x i1> [[TMP4]], <8 x i32> <i32 0, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15>
+; CHECK-NEXT: ret <8 x i1> [[TMP5]]
+;
+ %c1 = icmp eq i16 %x, 0
+ %c2 = icmp ne i16 %x, 1
+ %c3 = icmp ne i16 %x, 2
+ %c4 = icmp ne i16 %x, 3
+ %c5 = icmp ne i16 %x, 4
+ %c6 = icmp ne i16 %x, 5
+ %c7 = icmp ne i16 %x, 6
+ %c8 = icmp ne i16 %x, 7
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+; samesign is dropped on the vector compare, like for any cmp node; the
+; converted lanes stay correct since the vector lane is defined wherever the
+; original samesign scalar was poison.
+define <8 x i1> @samesign_lanes(i8 %x) {
+; CHECK-LABEL: define <8 x i1> @samesign_lanes(
+; CHECK-SAME: i8 [[X:%.*]]) {
+; CHECK-NEXT: [[C1:%.*]] = icmp samesign eq i8 [[X]], 0
+; CHECK-NEXT: [[C2:%.*]] = icmp samesign ult i8 [[X]], 2
+; CHECK-NEXT: [[C3:%.*]] = icmp samesign ult i8 [[X]], 3
+; CHECK-NEXT: [[C4:%.*]] = icmp samesign ult i8 [[X]], 4
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i8> poison, i8 [[X]], i64 0
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i8> [[TMP1]], <4 x i8> poison, <4 x i32> zeroinitializer
+; CHECK-NEXT: [[TMP5:%.*]] = icmp ult <4 x i8> [[TMP2]], <i8 5, i8 6, i8 7, i8 8>
+; CHECK-NEXT: [[I1:%.*]] = insertelement <8 x i1> poison, i1 [[C1]], i32 0
+; CHECK-NEXT: [[I2:%.*]] = insertelement <8 x i1> [[I1]], i1 [[C2]], i32 1
+; CHECK-NEXT: [[I3:%.*]] = insertelement <8 x i1> [[I2]], i1 [[C3]], i32 2
+; CHECK-NEXT: [[I4:%.*]] = insertelement <8 x i1> [[I3]], i1 [[C4]], i32 3
+; CHECK-NEXT: [[TMP4:%.*]] = shufflevector <4 x i1> [[TMP5]], <4 x i1> poison, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 poison, i32 poison, i32 poison, i32 poison>
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <8 x i1> [[I4]], <8 x i1> [[TMP4]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 8, i32 9, i32 10, i32 11>
+; CHECK-NEXT: ret <8 x i1> [[TMP3]]
+;
+ %c1 = icmp samesign eq i8 %x, 0
+ %c2 = icmp samesign ult i8 %x, 2
+ %c3 = icmp samesign ult i8 %x, 3
+ %c4 = icmp samesign ult i8 %x, 4
+ %c5 = icmp samesign ult i8 %x, 5
+ %c6 = icmp samesign ult i8 %x, 6
+ %c7 = icmp samesign ult i8 %x, 7
+ %c8 = icmp samesign ult i8 %x, 8
+ %i1 = insertelement <8 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <8 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <8 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <8 x i1> %i3, i1 %c4, i32 3
+ %i5 = insertelement <8 x i1> %i4, i1 %c5, i32 4
+ %i6 = insertelement <8 x i1> %i5, i1 %c6, i32 5
+ %i7 = insertelement <8 x i1> %i6, i1 %c7, i32 6
+ %i8 = insertelement <8 x i1> %i7, i1 %c8, i32 7
+ ret <8 x i1> %i8
+}
+
+; samesign is dropped: the i1 conversion flips the constant's sign.
+define <4 x i1> @samesign_i1_signflip(i1 %x, i1 %y, i1 %z, i1 %w) {
+; CHECK-LABEL: define <4 x i1> @samesign_i1_signflip(
+; CHECK-SAME: i1 [[X:%.*]], i1 [[Y:%.*]], i1 [[Z:%.*]], i1 [[W:%.*]]) {
+; CHECK-NEXT: [[C1:%.*]] = icmp samesign eq i1 [[X]], false
+; CHECK-NEXT: [[C2:%.*]] = icmp samesign ult i1 [[Y]], true
+; CHECK-NEXT: [[C3:%.*]] = icmp samesign ult i1 [[Z]], true
+; CHECK-NEXT: [[C4:%.*]] = icmp samesign ult i1 [[W]], true
+; CHECK-NEXT: [[I1:%.*]] = insertelement <4 x i1> poison, i1 [[C1]], i32 0
+; CHECK-NEXT: [[I2:%.*]] = insertelement <4 x i1> [[I1]], i1 [[C2]], i32 1
+; CHECK-NEXT: [[I3:%.*]] = insertelement <4 x i1> [[I2]], i1 [[C3]], i32 2
+; CHECK-NEXT: [[TMP5:%.*]] = insertelement <4 x i1> [[I3]], i1 [[C4]], i32 3
+; CHECK-NEXT: ret <4 x i1> [[TMP5]]
+;
+ %c1 = icmp samesign eq i1 %x, 0
+ %c2 = icmp samesign ult i1 %y, 1
+ %c3 = icmp samesign ult i1 %z, 1
+ %c4 = icmp samesign ult i1 %w, 1
+ %i1 = insertelement <4 x i1> poison, i1 %c1, i32 0
+ %i2 = insertelement <4 x i1> %i1, i1 %c2, i32 1
+ %i3 = insertelement <4 x i1> %i2, i1 %c3, i32 2
+ %i4 = insertelement <4 x i1> %i3, i1 %c4, i32 3
+ ret <4 x i1> %i4
+}
+
+; samesign is dropped: the compared operands are narrowed.
+define <4 x i1> @samesign_narrowed(i16 %a, i16 %b, i16 %c, i16 %d) {
+; CHECK-LABEL: define <4 x i1> @samesign_narrowed(
+; CHECK-SAME: i16 [[A:%.*]], i16 [[B:%.*]], i16 [[C:%.*]], i16 [[D:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <2 x i16> poison, i16 [[A]], i64 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertelement <2 x i16> [[TMP1]], i16 [[C]], i64 1
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <2 x i16> [[TMP2]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 0, i32 1>
+; CHECK-NEXT: [[TMP4:%.*]] = insertelement <2 x i16> poison, i16 [[B]], i64 0
+; CHECK-NEXT: [[TMP5:%.*]] = insertelement <2 x i16> [[TMP4]], i16 [[D]], i64 1
+; CHECK-NEXT: [[TMP6:%.*]] = shufflevector <2 x i16> [[TMP5]], <2 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 0>
+; CHECK-NEXT: [[TMP7:%.*]] = icmp ult <4 x i16> [[TMP3]], [[TMP6]]
+; CHECK-NEXT: ret <4 x i1> [[TMP7]]
+;
+ %a32 = zext i16 %a to i32
+ %b32 = zext i16 %b to i32
+ %c32 = zext i16 %c to i32
+ %d32 = zext i16 %d to i32
+ %r1 = icmp samesign ult i32 %a32, %b32
+ %r2 = icmp samesign ult i32 %c32, %d32
+ %r3 = icmp samesign ult i32 %a32, %d32
+ %r4 = icmp samesign ult i32 %c32, %b32
+ %i1 = insertelement <4 x i1> poison, i1 %r1, i32 0
+ %i2 = insertelement <4 x i1> %i1, i1 %r2, i32 1
+ %i3 = insertelement <4 x i1> %i2, i1 %r3, i32 2
+ %i4 = insertelement <4 x i1> %i3, i1 %r4, i32 3
+ ret <4 x i1> %i4
+}
+
+; The original issue pattern: compares feeding selects and stores.
+define void @selects(ptr noalias %out, ptr addrspace(11) %a, ptr addrspace(11) %b, i64 %n) {
+; CHECK-LABEL: define void @selects(
+; CHECK-SAME: ptr noalias [[OUT:%.*]], ptr addrspace(11) [[A:%.*]], ptr addrspace(11) [[B:%.*]], i64 [[N:%.*]]) {
+; CHECK-NEXT: [[X:%.*]] = trunc i64 [[N]] to i16
+; CHECK-NEXT: [[TMP1:%.*]] = insertelement <4 x i16> <i16 0, i16 poison, i16 poison, i16 poison>, i16 [[X]], i64 1
+; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i16> [[TMP1]], <4 x i16> poison, <4 x i32> <i32 0, i32 1, i32 1, i32 1>
+; CHECK-NEXT: [[TMP7:%.*]] = insertelement <4 x i16> <i16 poison, i16 2, i16 3, i16 4>, i16 [[X]], i64 0
+; CHECK-NEXT: [[TMP8:%.*]] = icmp eq <4 x i16> [[TMP2]], [[TMP7]]
+; CHECK-NEXT: [[TMP9:%.*]] = icmp ult <4 x i16> [[TMP2]], [[TMP7]]
+; CHECK-NEXT: [[TMP3:%.*]] = shufflevector <4 x i1> [[TMP8]], <4 x i1> [[TMP9]], <4 x i32> <i32 0, i32 5, i32 6, i32 7>
+; CHECK-NEXT: [[TMP4:%.*]] = load <4 x i16>, ptr addrspace(11) [[A]], align 2
+; CHECK-NEXT: [[TMP5:%.*]] = load <4 x i16>, ptr addrspace(11) [[B]], align 2
+; CHECK-NEXT: [[TMP6:%.*]] = select <4 x i1> [[TMP3]], <4 x i16> [[TMP5]], <4 x i16> [[TMP4]]
+; CHECK-NEXT: store <4 x i16> [[TMP6]], ptr [[OUT]], align 2
+; CHECK-NEXT: ret void
+;
+ %x = trunc i64 %n to i16
+ %c1 = icmp eq i16 %x, 0
+ %l1a = load i16, ptr addrspace(11) %a, align 2
+ %l1b = load i16, ptr addrspace(11) %b, align 2
+ %s1 = select i1 %c1, i16 %l1b, i16 %l1a
+ %c2 = icmp ult i16 %x, 2
+ %p2a = getelementptr i8, ptr addrspace(11) %a, i64 2
+ %p2b = getelementptr i8, ptr addrspace(11) %b, i64 2
+ %l2a = load i16, ptr addrspace(11) %p2a, align 2
+ %l2b = load i16, ptr addrspace(11) %p2b, align 2
+ %s2 = select i1 %c2, i16 %l2b, i16 %l2a
+ %c3 = icmp ult i16 %x, 3
+ %p3a = getelementptr i8, ptr addrspace(11) %a, i64 4
+ %p3b = getelementptr i8, ptr addrspace(11) %b, i64 4
+ %l3a = load i16, ptr addrspace(11) %p3a, align 2
+ %l3b = load i16, ptr addrspace(11) %p3b, align 2
+ %s3 = select i1 %c3, i16 %l3b, i16 %l3a
+ %c4 = icmp ult i16 %x, 4
+ %p4a = getelementptr i8, ptr addrspace(11) %a, i64 6
+ %p4b = getelementptr i8, ptr addrspace(11) %b, i64 6
+ %l4a = load i16, ptr addrspace(11) %p4a, align 2
+ %l4b = load i16, ptr addrspace(11) %p4b, align 2
+ %s4 = select i1 %c4, i16 %l4b, i16 %l4a
+ store i16 %s1, ptr %out, align 2
+ %o2 = getelementptr i8, ptr %out, i64 2
+ store i16 %s2, ptr %o2, align 2
+ %o3 = getelementptr i8, ptr %out, i64 4
+ store i16 %s3, ptr %o3, align 2
+ %o4 = getelementptr i8, ptr %out, i64 6
+ store i16 %s4, ptr %o4, align 2
+ ret void
+}
More information about the llvm-commits
mailing list