| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 |
| ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE2 |
| ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse4.2 | FileCheck %s --check-prefixes=CHECK,SSE,SSE4 |
| ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s --check-prefixes=CHECK,AVX2 |
| ; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx512vl | FileCheck %s --check-prefixes=CHECK,AVX512 |
| |
| declare void @use(<4 x i1>) |
| |
| ; icmp - eq v4i32 is cheap |
| |
| define <4 x i32> @shuf_icmp_eq_v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32> %w) { |
| ; SSE-LABEL: define <4 x i32> @shuf_icmp_eq_v4i32( |
| ; SSE-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]], <4 x i32> [[W:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; SSE-NEXT: [[C0:%.*]] = icmp eq <4 x i32> [[X]], [[Y]] |
| ; SSE-NEXT: [[C1:%.*]] = icmp eq <4 x i32> [[Z]], [[W]] |
| ; SSE-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[C0]], <4 x i1> [[C1]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; SSE-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; SSE-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; AVX2-LABEL: define <4 x i32> @shuf_icmp_eq_v4i32( |
| ; AVX2-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]], <4 x i32> [[W:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; AVX2-NEXT: [[C0:%.*]] = icmp eq <4 x i32> [[X]], [[Y]] |
| ; AVX2-NEXT: [[C1:%.*]] = icmp eq <4 x i32> [[Z]], [[W]] |
| ; AVX2-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[C0]], <4 x i1> [[C1]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; AVX2-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; AVX2-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; AVX512-LABEL: define <4 x i32> @shuf_icmp_eq_v4i32( |
| ; AVX512-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]], <4 x i32> [[W:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; AVX512-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Z]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; AVX512-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[W]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; AVX512-NEXT: [[S:%.*]] = icmp eq <4 x i32> [[TMP1]], [[TMP2]] |
| ; AVX512-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; AVX512-NEXT: ret <4 x i32> [[R]] |
| ; |
| %c0 = icmp eq <4 x i32> %x, %y |
| %c1 = icmp eq <4 x i32> %z, %w |
| %s = shufflevector <4 x i1> %c0, <4 x i1> %c1, <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; icmp - eq v2i64 is only cheap on SSE4+ targets with PCMPEQQ |
| |
| define <2 x i64> @shuf_icmp_eq_v2i64(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z, <2 x i64> %w) { |
| ; SSE2-LABEL: define <2 x i64> @shuf_icmp_eq_v2i64( |
| ; SSE2-SAME: <2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], <2 x i64> [[Z:%.*]], <2 x i64> [[W:%.*]]) #[[ATTR0]] { |
| ; SSE2-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[X]], <2 x i64> [[Z]], <2 x i32> <i32 1, i32 3> |
| ; SSE2-NEXT: [[TMP2:%.*]] = shufflevector <2 x i64> [[Y]], <2 x i64> [[W]], <2 x i32> <i32 1, i32 3> |
| ; SSE2-NEXT: [[S:%.*]] = icmp eq <2 x i64> [[TMP1]], [[TMP2]] |
| ; SSE2-NEXT: [[R:%.*]] = sext <2 x i1> [[S]] to <2 x i64> |
| ; SSE2-NEXT: ret <2 x i64> [[R]] |
| ; |
| ; SSE4-LABEL: define <2 x i64> @shuf_icmp_eq_v2i64( |
| ; SSE4-SAME: <2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], <2 x i64> [[Z:%.*]], <2 x i64> [[W:%.*]]) #[[ATTR0]] { |
| ; SSE4-NEXT: [[C0:%.*]] = icmp eq <2 x i64> [[X]], [[Y]] |
| ; SSE4-NEXT: [[C1:%.*]] = icmp eq <2 x i64> [[Z]], [[W]] |
| ; SSE4-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[C0]], <2 x i1> [[C1]], <2 x i32> <i32 1, i32 3> |
| ; SSE4-NEXT: [[R:%.*]] = sext <2 x i1> [[S]] to <2 x i64> |
| ; SSE4-NEXT: ret <2 x i64> [[R]] |
| ; |
| ; AVX2-LABEL: define <2 x i64> @shuf_icmp_eq_v2i64( |
| ; AVX2-SAME: <2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], <2 x i64> [[Z:%.*]], <2 x i64> [[W:%.*]]) #[[ATTR0]] { |
| ; AVX2-NEXT: [[C0:%.*]] = icmp eq <2 x i64> [[X]], [[Y]] |
| ; AVX2-NEXT: [[C1:%.*]] = icmp eq <2 x i64> [[Z]], [[W]] |
| ; AVX2-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[C0]], <2 x i1> [[C1]], <2 x i32> <i32 1, i32 3> |
| ; AVX2-NEXT: [[R:%.*]] = sext <2 x i1> [[S]] to <2 x i64> |
| ; AVX2-NEXT: ret <2 x i64> [[R]] |
| ; |
| ; AVX512-LABEL: define <2 x i64> @shuf_icmp_eq_v2i64( |
| ; AVX512-SAME: <2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], <2 x i64> [[Z:%.*]], <2 x i64> [[W:%.*]]) #[[ATTR0]] { |
| ; AVX512-NEXT: [[TMP1:%.*]] = shufflevector <2 x i64> [[X]], <2 x i64> [[Z]], <2 x i32> <i32 1, i32 3> |
| ; AVX512-NEXT: [[TMP2:%.*]] = shufflevector <2 x i64> [[Y]], <2 x i64> [[W]], <2 x i32> <i32 1, i32 3> |
| ; AVX512-NEXT: [[S:%.*]] = icmp eq <2 x i64> [[TMP1]], [[TMP2]] |
| ; AVX512-NEXT: [[R:%.*]] = sext <2 x i1> [[S]] to <2 x i64> |
| ; AVX512-NEXT: ret <2 x i64> [[R]] |
| ; |
| %c0 = icmp eq <2 x i64> %x, %y |
| %c1 = icmp eq <2 x i64> %z, %w |
| %s = shufflevector <2 x i1> %c0, <2 x i1> %c1, <2 x i32> <i32 1, i32 3> |
| %r = sext <2 x i1> %s to <2 x i64> |
| ret <2 x i64> %r |
| } |
| |
| ; icmp - ugt v4i32 is expensive |
| |
| define <4 x i32> @shuf_icmp_ugt_v4i32(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32> %w) { |
| ; CHECK-LABEL: define <4 x i32> @shuf_icmp_ugt_v4i32( |
| ; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]], <4 x i32> [[W:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> [[Z]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[W]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; CHECK-NEXT: [[S:%.*]] = icmp ugt <4 x i32> [[TMP1]], [[TMP2]] |
| ; CHECK-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %c0 = icmp ugt <4 x i32> %x, %y |
| %c1 = icmp ugt <4 x i32> %z, %w |
| %s = shufflevector <4 x i1> %c0, <4 x i1> %c1, <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; Common operand is op0 of the fcmps (CMPPS cheaper on SSE4+). |
| |
| define <4 x i32> @shuf_fcmp_oeq_v4i32(<4 x float> %x, <4 x float> %y, <4 x float> %z) { |
| ; SSE2-LABEL: define <4 x i32> @shuf_fcmp_oeq_v4i32( |
| ; SSE2-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x float> [[Z:%.*]]) #[[ATTR0]] { |
| ; SSE2-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[X]], <4 x float> poison, <4 x i32> <i32 poison, i32 poison, i32 0, i32 0> |
| ; SSE2-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[Y]], <4 x float> [[Z]], <4 x i32> <i32 poison, i32 poison, i32 4, i32 0> |
| ; SSE2-NEXT: [[S:%.*]] = fcmp oeq <4 x float> [[TMP1]], [[TMP2]] |
| ; SSE2-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; SSE2-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; SSE4-LABEL: define <4 x i32> @shuf_fcmp_oeq_v4i32( |
| ; SSE4-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x float> [[Z:%.*]]) #[[ATTR0]] { |
| ; SSE4-NEXT: [[B0:%.*]] = fcmp oeq <4 x float> [[X]], [[Y]] |
| ; SSE4-NEXT: [[B1:%.*]] = fcmp oeq <4 x float> [[X]], [[Z]] |
| ; SSE4-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[B0]], <4 x i1> [[B1]], <4 x i32> <i32 poison, i32 poison, i32 4, i32 0> |
| ; SSE4-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; SSE4-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; AVX2-LABEL: define <4 x i32> @shuf_fcmp_oeq_v4i32( |
| ; AVX2-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x float> [[Z:%.*]]) #[[ATTR0]] { |
| ; AVX2-NEXT: [[B0:%.*]] = fcmp oeq <4 x float> [[X]], [[Y]] |
| ; AVX2-NEXT: [[B1:%.*]] = fcmp oeq <4 x float> [[X]], [[Z]] |
| ; AVX2-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[B0]], <4 x i1> [[B1]], <4 x i32> <i32 poison, i32 poison, i32 4, i32 0> |
| ; AVX2-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; AVX2-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; AVX512-LABEL: define <4 x i32> @shuf_fcmp_oeq_v4i32( |
| ; AVX512-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x float> [[Z:%.*]]) #[[ATTR0]] { |
| ; AVX512-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[X]], <4 x float> poison, <4 x i32> <i32 poison, i32 poison, i32 0, i32 0> |
| ; AVX512-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[Y]], <4 x float> [[Z]], <4 x i32> <i32 poison, i32 poison, i32 4, i32 0> |
| ; AVX512-NEXT: [[S:%.*]] = fcmp oeq <4 x float> [[TMP1]], [[TMP2]] |
| ; AVX512-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; AVX512-NEXT: ret <4 x i32> [[R]] |
| ; |
| %b0 = fcmp oeq <4 x float> %x, %y |
| %b1 = fcmp oeq <4 x float> %x, %z |
| %s = shufflevector <4 x i1> %b0, <4 x i1> %b1, <4 x i32> <i32 poison, i32 poison, i32 4, i32 0> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; For commutative instructions, common operand may be swapped |
| |
| define <4 x i32> @shuf_fcmp_one_v4f32_swap(<4 x float> %x, <4 x float> %y, <4 x float> %z) { |
| ; CHECK-LABEL: define <4 x i32> @shuf_fcmp_one_v4f32_swap( |
| ; CHECK-SAME: <4 x float> [[X:%.*]], <4 x float> [[Y:%.*]], <4 x float> [[Z:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[Y]], <4 x float> [[Z]], <4 x i32> <i32 0, i32 3, i32 4, i32 7> |
| ; CHECK-NEXT: [[TMP2:%.*]] = shufflevector <4 x float> [[X]], <4 x float> poison, <4 x i32> <i32 0, i32 3, i32 0, i32 3> |
| ; CHECK-NEXT: [[S:%.*]] = fcmp one <4 x float> [[TMP1]], [[TMP2]] |
| ; CHECK-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %b0 = fcmp one <4 x float> %x, %y |
| %b1 = fcmp one <4 x float> %z, %x |
| %s = shufflevector <4 x i1> %b0, <4 x i1> %b1, <4 x i32> <i32 0, i32 3, i32 4, i32 7> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; non-commutative pred, but common op0 |
| |
| define <4 x i32> @shuf_icmp_sgt_v4i32_swap(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z) { |
| ; SSE-LABEL: define <4 x i32> @shuf_icmp_sgt_v4i32_swap( |
| ; SSE-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]]) #[[ATTR0]] { |
| ; SSE-NEXT: [[B0:%.*]] = icmp sgt <4 x i32> [[X]], [[Y]] |
| ; SSE-NEXT: [[B1:%.*]] = icmp sgt <4 x i32> [[X]], [[Z]] |
| ; SSE-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[B0]], <4 x i1> [[B1]], <4 x i32> <i32 3, i32 1, i32 1, i32 6> |
| ; SSE-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; SSE-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; AVX2-LABEL: define <4 x i32> @shuf_icmp_sgt_v4i32_swap( |
| ; AVX2-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]]) #[[ATTR0]] { |
| ; AVX2-NEXT: [[B0:%.*]] = icmp sgt <4 x i32> [[X]], [[Y]] |
| ; AVX2-NEXT: [[B1:%.*]] = icmp sgt <4 x i32> [[X]], [[Z]] |
| ; AVX2-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[B0]], <4 x i1> [[B1]], <4 x i32> <i32 3, i32 1, i32 1, i32 6> |
| ; AVX2-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; AVX2-NEXT: ret <4 x i32> [[R]] |
| ; |
| ; AVX512-LABEL: define <4 x i32> @shuf_icmp_sgt_v4i32_swap( |
| ; AVX512-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]]) #[[ATTR0]] { |
| ; AVX512-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[X]], <4 x i32> poison, <4 x i32> <i32 3, i32 1, i32 1, i32 2> |
| ; AVX512-NEXT: [[TMP2:%.*]] = shufflevector <4 x i32> [[Y]], <4 x i32> [[Z]], <4 x i32> <i32 3, i32 1, i32 1, i32 6> |
| ; AVX512-NEXT: [[S:%.*]] = icmp sgt <4 x i32> [[TMP1]], [[TMP2]] |
| ; AVX512-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; AVX512-NEXT: ret <4 x i32> [[R]] |
| ; |
| %b0 = icmp sgt <4 x i32> %x, %y |
| %b1 = icmp sgt <4 x i32> %x, %z |
| %s = shufflevector <4 x i1> %b0, <4 x i1> %b1, <4 x i32> <i32 3, i32 1, i32 1, i32 6> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; negative test - mismatched opcodes |
| |
| define <2 x i64> @shuf_icmp_fcmp_v2i64_mismatch_opcode(<2 x i64> %x, <2 x i64> %y, <2 x double> %z, <2 x double> %w) { |
| ; CHECK-LABEL: define <2 x i64> @shuf_icmp_fcmp_v2i64_mismatch_opcode( |
| ; CHECK-SAME: <2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], <2 x double> [[Z:%.*]], <2 x double> [[W:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[B0:%.*]] = icmp eq <2 x i64> [[X]], [[Y]] |
| ; CHECK-NEXT: [[B1:%.*]] = fcmp oeq <2 x double> [[Z]], [[W]] |
| ; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[B0]], <2 x i1> [[B1]], <2 x i32> <i32 3, i32 0> |
| ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[S]] to <2 x i64> |
| ; CHECK-NEXT: ret <2 x i64> [[R]] |
| ; |
| %b0 = icmp eq <2 x i64> %x, %y |
| %b1 = fcmp oeq <2 x double> %z, %w |
| %s = shufflevector <2 x i1> %b0, <2 x i1> %b1, <2 x i32> <i32 3, i32 0> |
| %r = sext <2 x i1> %s to <2 x i64> |
| ret <2 x i64> %r |
| } |
| |
| ; negative test - mismatched predicates |
| |
| define <2 x i64> @shuf_icmp_eq_sgt_v2i64_mismatch_predicate(<2 x i64> %x, <2 x i64> %y, <2 x i64> %z) { |
| ; CHECK-LABEL: define <2 x i64> @shuf_icmp_eq_sgt_v2i64_mismatch_predicate( |
| ; CHECK-SAME: <2 x i64> [[X:%.*]], <2 x i64> [[Y:%.*]], <2 x i64> [[Z:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[B0:%.*]] = icmp eq <2 x i64> [[X]], [[Y]] |
| ; CHECK-NEXT: [[B1:%.*]] = icmp sgt <2 x i64> [[Z]], [[Y]] |
| ; CHECK-NEXT: [[S:%.*]] = shufflevector <2 x i1> [[B0]], <2 x i1> [[B1]], <2 x i32> <i32 3, i32 0> |
| ; CHECK-NEXT: [[R:%.*]] = sext <2 x i1> [[S]] to <2 x i64> |
| ; CHECK-NEXT: ret <2 x i64> [[R]] |
| ; |
| %b0 = icmp eq <2 x i64> %x, %y |
| %b1 = icmp sgt <2 x i64> %z, %y |
| %s = shufflevector <2 x i1> %b0, <2 x i1> %b1, <2 x i32> <i32 3, i32 0> |
| %r = sext <2 x i1> %s to <2 x i64> |
| ret <2 x i64> %r |
| } |
| |
| ; negative test - mismatched types |
| |
| define <4 x i32> @shuf_icmp_eq_v4i64_v4i32_mismatch_type(<4 x i64> %x, <4 x i64> %y, <4 x i32> %z, <4 x i32> %w) { |
| ; CHECK-LABEL: define <4 x i32> @shuf_icmp_eq_v4i64_v4i32_mismatch_type( |
| ; CHECK-SAME: <4 x i64> [[X:%.*]], <4 x i64> [[Y:%.*]], <4 x i32> [[Z:%.*]], <4 x i32> [[W:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[B0:%.*]] = icmp eq <4 x i64> [[X]], [[Y]] |
| ; CHECK-NEXT: [[B1:%.*]] = icmp eq <4 x i32> [[Z]], [[W]] |
| ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[B0]], <4 x i1> [[B1]], <4 x i32> <i32 3, i32 1, i32 1, i32 6> |
| ; CHECK-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %b0 = icmp eq <4 x i64> %x, %y |
| %b1 = icmp eq <4 x i32> %z, %w |
| %s = shufflevector <4 x i1> %b0, <4 x i1> %b1, <4 x i32> <i32 3, i32 1, i32 1, i32 6> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; negative test - uses |
| |
| define <4 x i32> @shuf_icmp_ugt_v4i32_use(<4 x i32> %x, <4 x i32> %y, <4 x i32> %z, <4 x i32> %w) { |
| ; CHECK-LABEL: define <4 x i32> @shuf_icmp_ugt_v4i32_use( |
| ; CHECK-SAME: <4 x i32> [[X:%.*]], <4 x i32> [[Y:%.*]], <4 x i32> [[Z:%.*]], <4 x i32> [[W:%.*]]) #[[ATTR0]] { |
| ; CHECK-NEXT: [[C0:%.*]] = icmp ugt <4 x i32> [[X]], [[Y]] |
| ; CHECK-NEXT: [[C1:%.*]] = icmp ugt <4 x i32> [[Z]], [[W]] |
| ; CHECK-NEXT: call void @use(<4 x i1> [[C0]]) |
| ; CHECK-NEXT: [[S:%.*]] = shufflevector <4 x i1> [[C0]], <4 x i1> [[C1]], <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| ; CHECK-NEXT: [[R:%.*]] = sext <4 x i1> [[S]] to <4 x i32> |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %c0 = icmp ugt <4 x i32> %x, %y |
| %c1 = icmp ugt <4 x i32> %z, %w |
| call void @use(<4 x i1> %c0) |
| %s = shufflevector <4 x i1> %c0, <4 x i1> %c1, <4 x i32> <i32 1, i32 3, i32 5, i32 7> |
| %r = sext <4 x i1> %s to <4 x i32> |
| ret <4 x i32> %r |
| } |
| |
| ; PR121110 - don't merge equivalent (but not matching) predicates |
| |
| define <2 x i1> @PR121110() { |
| ; CHECK-LABEL: define <2 x i1> @PR121110( |
| ; CHECK-SAME: ) #[[ATTR0]] { |
| ; CHECK-NEXT: [[UGT:%.*]] = icmp samesign ugt <2 x i32> zeroinitializer, zeroinitializer |
| ; CHECK-NEXT: [[SGT:%.*]] = icmp sgt <2 x i32> zeroinitializer, <i32 6, i32 -4> |
| ; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i1> [[UGT]], <2 x i1> [[SGT]], <2 x i32> <i32 0, i32 3> |
| ; CHECK-NEXT: ret <2 x i1> [[RES]] |
| ; |
| %ugt = icmp samesign ugt <2 x i32> < i32 0, i32 0 >, < i32 0, i32 0 > |
| %sgt = icmp sgt <2 x i32> < i32 0, i32 0 >, < i32 6, i32 4294967292 > |
| %res = shufflevector <2 x i1> %ugt, <2 x i1> %sgt, <2 x i32> <i32 0, i32 3> |
| ret <2 x i1> %res |
| } |
| |
| define <2 x i1> @PR121110_commute() { |
| ; CHECK-LABEL: define <2 x i1> @PR121110_commute( |
| ; CHECK-SAME: ) #[[ATTR0]] { |
| ; CHECK-NEXT: [[SGT:%.*]] = icmp sgt <2 x i32> zeroinitializer, <i32 6, i32 -4> |
| ; CHECK-NEXT: [[UGT:%.*]] = icmp samesign ugt <2 x i32> zeroinitializer, zeroinitializer |
| ; CHECK-NEXT: [[RES:%.*]] = shufflevector <2 x i1> [[SGT]], <2 x i1> [[UGT]], <2 x i32> <i32 0, i32 3> |
| ; CHECK-NEXT: ret <2 x i1> [[RES]] |
| ; |
| %sgt = icmp sgt <2 x i32> < i32 0, i32 0 >, < i32 6, i32 4294967292 > |
| %ugt = icmp samesign ugt <2 x i32> < i32 0, i32 0 >, < i32 0, i32 0 > |
| %res = shufflevector <2 x i1> %sgt, <2 x i1> %ugt, <2 x i32> <i32 0, i32 3> |
| ret <2 x i1> %res |
| } |