| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=vector-combine %s -S -o - | FileCheck %s |
| |
| define <8 x i16> @two_deinterleave2_mul_xor_trunc(<8 x i32> %a, <8 x i32> %b) { |
| ; CHECK-LABEL: define <8 x i16> @two_deinterleave2_mul_xor_trunc( |
| ; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i32> [[A]], [[B]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = xor <8 x i32> [[TMP1]], splat (i32 7) |
| ; CHECK-NEXT: [[R:%.*]] = trunc <8 x i32> [[TMP2]] to <8 x i16> |
| ; CHECK-NEXT: ret <8 x i16> [[R]] |
| ; |
| %da = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %a) |
| %a0 = extractvalue { <4 x i32>, <4 x i32> } %da, 0 |
| %a1 = extractvalue { <4 x i32>, <4 x i32> } %da, 1 |
| %db = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %b) |
| %b0 = extractvalue { <4 x i32>, <4 x i32> } %db, 0 |
| %b1 = extractvalue { <4 x i32>, <4 x i32> } %db, 1 |
| %m0 = mul <4 x i32> %a0, %b0 |
| %m1 = mul <4 x i32> %a1, %b1 |
| %x0 = xor <4 x i32> %m0, splat (i32 7) |
| %x1 = xor <4 x i32> %m1, splat (i32 7) |
| %t0 = trunc <4 x i32> %x0 to <4 x i16> |
| %t1 = trunc <4 x i32> %x1 to <4 x i16> |
| %r = call <8 x i16> @llvm.vector.interleave2.v8i16(<4 x i16> %t0, <4 x i16> %t1) |
| ret <8 x i16> %r |
| } |
| |
| define <vscale x 8 x i16> @two_deinterleave2_independent_chains(<vscale x 8 x i16> %a, <vscale x 8 x i16> %b) { |
| ; CHECK-LABEL: define <vscale x 8 x i16> @two_deinterleave2_independent_chains( |
| ; CHECK-SAME: <vscale x 8 x i16> [[A:%.*]], <vscale x 8 x i16> [[B:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = add <vscale x 8 x i16> [[A]], splat (i16 1) |
| ; CHECK-NEXT: [[TMP2:%.*]] = xor <vscale x 8 x i16> [[B]], splat (i16 3) |
| ; CHECK-NEXT: [[TMP3:%.*]] = mul <vscale x 8 x i16> [[TMP1]], [[TMP2]] |
| ; CHECK-NEXT: [[R:%.*]] = sub <vscale x 8 x i16> [[TMP3]], splat (i16 5) |
| ; CHECK-NEXT: ret <vscale x 8 x i16> [[R]] |
| ; |
| %da = call { <vscale x 4 x i16>, <vscale x 4 x i16> } @llvm.vector.deinterleave2.nxv8i16(<vscale x 8 x i16> %a) |
| %a0 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16> } %da, 0 |
| %a1 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16> } %da, 1 |
| %db = call { <vscale x 4 x i16>, <vscale x 4 x i16> } @llvm.vector.deinterleave2.nxv8i16(<vscale x 8 x i16> %b) |
| %b0 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16> } %db, 0 |
| %b1 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16> } %db, 1 |
| %aa0 = add <vscale x 4 x i16> %a0, splat (i16 1) |
| %aa1 = add <vscale x 4 x i16> %a1, splat (i16 1) |
| %bb0 = xor <vscale x 4 x i16> %b0, splat (i16 3) |
| %bb1 = xor <vscale x 4 x i16> %b1, splat (i16 3) |
| %m0 = mul <vscale x 4 x i16> %aa0, %bb0 |
| %m1 = mul <vscale x 4 x i16> %aa1, %bb1 |
| %s0 = sub <vscale x 4 x i16> %m0, splat (i16 5) |
| %s1 = sub <vscale x 4 x i16> %m1, splat (i16 5) |
| %r = call <vscale x 8 x i16> @llvm.vector.interleave2.nxv8i16(<vscale x 4 x i16> %s0, <vscale x 4 x i16> %s1) |
| ret <vscale x 8 x i16> %r |
| } |
| |
| define <vscale x 6 x i32> @two_deinterleave3_add(<vscale x 6 x i32> %a, <vscale x 6 x i32> %b) { |
| ; CHECK-LABEL: define <vscale x 6 x i32> @two_deinterleave3_add( |
| ; CHECK-SAME: <vscale x 6 x i32> [[A:%.*]], <vscale x 6 x i32> [[B:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = add <vscale x 6 x i32> [[A]], [[B]] |
| ; CHECK-NEXT: ret <vscale x 6 x i32> [[R]] |
| ; |
| %da = call { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } @llvm.vector.deinterleave3.nxv6i32(<vscale x 6 x i32> %a) |
| %a0 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %da, 0 |
| %a1 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %da, 1 |
| %a2 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %da, 2 |
| %db = call { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } @llvm.vector.deinterleave3.nxv6i32(<vscale x 6 x i32> %b) |
| %b0 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %db, 0 |
| %b1 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %db, 1 |
| %b2 = extractvalue { <vscale x 2 x i32>, <vscale x 2 x i32>, <vscale x 2 x i32> } %db, 2 |
| %s0 = add <vscale x 2 x i32> %a0, %b0 |
| %s1 = add <vscale x 2 x i32> %a1, %b1 |
| %s2 = add <vscale x 2 x i32> %a2, %b2 |
| %r = call <vscale x 6 x i32> @llvm.vector.interleave3.nxv6i32(<vscale x 2 x i32> %s0, <vscale x 2 x i32> %s1, <vscale x 2 x i32> %s2) |
| ret <vscale x 6 x i32> %r |
| } |
| |
| define <4 x i32> @negative_deinterleave2_mixed_sources( |
| ; CHECK-LABEL: define <4 x i32> @negative_deinterleave2_mixed_sources( |
| ; CHECK-SAME: <4 x i32> [[A:%.*]], <4 x i32> [[B:%.*]], <4 x i32> [[C:%.*]]) { |
| ; CHECK-NEXT: [[DA:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> [[A]]) |
| ; CHECK-NEXT: [[A0:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[DA]], 0 |
| ; CHECK-NEXT: [[A1:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[DA]], 1 |
| ; CHECK-NEXT: [[DB:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> [[B]]) |
| ; CHECK-NEXT: [[B0:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[DB]], 0 |
| ; CHECK-NEXT: [[DC:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> [[C]]) |
| ; CHECK-NEXT: [[C1:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[DC]], 1 |
| ; CHECK-NEXT: [[S0:%.*]] = add <2 x i32> [[A0]], [[B0]] |
| ; CHECK-NEXT: [[S1:%.*]] = add <2 x i32> [[A1]], [[C1]] |
| ; CHECK-NEXT: [[R:%.*]] = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> [[S0]], <2 x i32> [[S1]]) |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| <4 x i32> %a, <4 x i32> %b, <4 x i32> %c) { |
| %da = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %a) |
| %a0 = extractvalue { <2 x i32>, <2 x i32> } %da, 0 |
| %a1 = extractvalue { <2 x i32>, <2 x i32> } %da, 1 |
| %db = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %b) |
| %b0 = extractvalue { <2 x i32>, <2 x i32> } %db, 0 |
| %dc = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %c) |
| %c1 = extractvalue { <2 x i32>, <2 x i32> } %dc, 1 |
| %s0 = add <2 x i32> %a0, %b0 |
| %s1 = add <2 x i32> %a1, %c1 |
| %r = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %s0, <2 x i32> %s1) |
| ret <4 x i32> %r |
| } |
| |
| define <8 x i32> @three_deinterleave2_tree_with_splats(<8 x i32> %a, <8 x i32> %b, <8 x i32> %c) { |
| ; CHECK-LABEL: define <8 x i32> @three_deinterleave2_tree_with_splats( |
| ; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B:%.*]], <8 x i32> [[C:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = mul <8 x i32> [[A]], [[B]] |
| ; CHECK-NEXT: [[TMP2:%.*]] = xor <8 x i32> [[TMP1]], splat (i32 7) |
| ; CHECK-NEXT: [[TMP3:%.*]] = add <8 x i32> [[TMP2]], [[C]] |
| ; CHECK-NEXT: [[R:%.*]] = shl <8 x i32> [[TMP3]], splat (i32 1) |
| ; CHECK-NEXT: ret <8 x i32> [[R]] |
| ; |
| %da = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %a) |
| %a0 = extractvalue { <4 x i32>, <4 x i32> } %da, 0 |
| %a1 = extractvalue { <4 x i32>, <4 x i32> } %da, 1 |
| %db = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %b) |
| %b0 = extractvalue { <4 x i32>, <4 x i32> } %db, 0 |
| %b1 = extractvalue { <4 x i32>, <4 x i32> } %db, 1 |
| %dc = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %c) |
| %c0 = extractvalue { <4 x i32>, <4 x i32> } %dc, 0 |
| %c1 = extractvalue { <4 x i32>, <4 x i32> } %dc, 1 |
| %m0 = mul <4 x i32> %a0, %b0 |
| %m1 = mul <4 x i32> %a1, %b1 |
| %x0 = xor <4 x i32> %m0, splat (i32 7) |
| %x1 = xor <4 x i32> %m1, splat (i32 7) |
| %s0 = add <4 x i32> %x0, %c0 |
| %s1 = add <4 x i32> %x1, %c1 |
| %t0 = shl <4 x i32> %s0, splat (i32 1) |
| %t1 = shl <4 x i32> %s1, splat (i32 1) |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %t0, <4 x i32> %t1) |
| ret <8 x i32> %r |
| } |
| |
| define <8 x i32> @deinterleave4_only_2_extracts_used(<16 x i32> %a) { |
| ; CHECK-LABEL: define <8 x i32> @deinterleave4_only_2_extracts_used( |
| ; CHECK-SAME: <16 x i32> [[A:%.*]]) { |
| ; CHECK-NEXT: [[DA:%.*]] = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.vector.deinterleave4.v16i32(<16 x i32> [[A]]) |
| ; CHECK-NEXT: [[A0:%.*]] = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } [[DA]], 0 |
| ; CHECK-NEXT: [[A1:%.*]] = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } [[DA]], 1 |
| ; CHECK-NEXT: [[M0:%.*]] = mul <4 x i32> [[A0]], [[A0]] |
| ; CHECK-NEXT: [[M1:%.*]] = mul <4 x i32> [[A1]], [[A1]] |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> [[M0]], <4 x i32> [[M1]]) |
| ; CHECK-NEXT: ret <8 x i32> [[R]] |
| ; |
| %da = call { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } @llvm.vector.deinterleave4(<16 x i32> %a) |
| %a0 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %da, 0 |
| %a1 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>, <4 x i32> } %da, 1 |
| %m0 = mul <4 x i32> %a0, %a0 |
| %m1 = mul <4 x i32> %a1, %a1 |
| %r = call <8 x i32> @llvm.vector.interleave2(<4 x i32> %m0, <4 x i32> %m1) |
| ret <8 x i32> %r |
| } |
| |
| define <20 x i32> @interleave__extracts_of_different_deinterleave(<12 x i32> %a, <8 x i32> %b) { |
| ; CHECK-LABEL: define <20 x i32> @interleave__extracts_of_different_deinterleave( |
| ; CHECK-SAME: <12 x i32> [[A:%.*]], <8 x i32> [[B:%.*]]) { |
| ; CHECK-NEXT: [[DA:%.*]] = call { <4 x i32>, <4 x i32>, <4 x i32> } @llvm.vector.deinterleave3.v12i32(<12 x i32> [[A]]) |
| ; CHECK-NEXT: [[A0:%.*]] = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } [[DA]], 0 |
| ; CHECK-NEXT: [[A1:%.*]] = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } [[DA]], 1 |
| ; CHECK-NEXT: [[A2:%.*]] = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } [[DA]], 2 |
| ; CHECK-NEXT: [[DB:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[B]]) |
| ; CHECK-NEXT: [[B0:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DB]], 0 |
| ; CHECK-NEXT: [[B1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DB]], 1 |
| ; CHECK-NEXT: [[M0:%.*]] = mul <4 x i32> [[A0]], [[A0]] |
| ; CHECK-NEXT: [[M1:%.*]] = mul <4 x i32> [[A1]], [[A1]] |
| ; CHECK-NEXT: [[M2:%.*]] = mul <4 x i32> [[A2]], [[A2]] |
| ; CHECK-NEXT: [[M3:%.*]] = mul <4 x i32> [[B0]], [[B0]] |
| ; CHECK-NEXT: [[M4:%.*]] = mul <4 x i32> [[B1]], [[B1]] |
| ; CHECK-NEXT: [[R:%.*]] = call <20 x i32> @llvm.vector.interleave5.v20i32(<4 x i32> [[M0]], <4 x i32> [[M1]], <4 x i32> [[M2]], <4 x i32> [[M3]], <4 x i32> [[M4]]) |
| ; CHECK-NEXT: ret <20 x i32> [[R]] |
| ; |
| %da = call { <4 x i32>, <4 x i32>, <4 x i32>} @llvm.vector.deinterleave3(<12 x i32> %a) |
| %a0 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32>} %da, 0 |
| %a1 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %da, 1 |
| %a2 = extractvalue { <4 x i32>, <4 x i32>, <4 x i32> } %da, 2 |
| |
| %db = call { <4 x i32>, <4 x i32>} @llvm.vector.deinterleave2(<8 x i32> %b) |
| %b0 = extractvalue { <4 x i32>, <4 x i32>} %db, 0 |
| %b1 = extractvalue { <4 x i32>, <4 x i32>} %db, 1 |
| |
| %m0 = mul <4 x i32> %a0, %a0 |
| %m1 = mul <4 x i32> %a1, %a1 |
| %m2 = mul <4 x i32> %a2, %a2 |
| %m3 = mul <4 x i32> %b0, %b0 |
| %m4 = mul <4 x i32> %b1, %b1 |
| %r = call <20 x i32> @llvm.vector.interleave5(<4 x i32> %m0, <4 x i32> %m1, <4 x i32> %m2, <4 x i32> %m3, <4 x i32> %m4) |
| ret <20 x i32> %r |
| } |
| |
| define <4 x i32> @deinterleave2_extract_used_twice_in_member(<4 x i32> %a) { |
| ; CHECK-LABEL: define <4 x i32> @deinterleave2_extract_used_twice_in_member( |
| ; CHECK-SAME: <4 x i32> [[A:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = mul <4 x i32> [[A]], [[A]] |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %da = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %a) |
| %a0 = extractvalue { <2 x i32>, <2 x i32> } %da, 0 |
| %a1 = extractvalue { <2 x i32>, <2 x i32> } %da, 1 |
| %m0 = mul <2 x i32> %a0, %a0 |
| %m1 = mul <2 x i32> %a1, %a1 |
| %r = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %m0, <2 x i32> %m1) |
| ret <4 x i32> %r |
| } |
| |
| define <4 x i32> @negative_deinterleave2_shared_non_splat_operand(<4 x i32> %a, <2 x i32> %x) { |
| ; CHECK-LABEL: define <4 x i32> @negative_deinterleave2_shared_non_splat_operand( |
| ; CHECK-SAME: <4 x i32> [[A:%.*]], <2 x i32> [[X:%.*]]) { |
| ; CHECK-NEXT: [[DA:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> [[A]]) |
| ; CHECK-NEXT: [[A0:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[DA]], 0 |
| ; CHECK-NEXT: [[A1:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[DA]], 1 |
| ; CHECK-NEXT: [[S0:%.*]] = add <2 x i32> [[A0]], [[X]] |
| ; CHECK-NEXT: [[S1:%.*]] = add <2 x i32> [[A1]], [[X]] |
| ; CHECK-NEXT: [[R:%.*]] = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> [[S0]], <2 x i32> [[S1]]) |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %da = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %a) |
| %a0 = extractvalue { <2 x i32>, <2 x i32> } %da, 0 |
| %a1 = extractvalue { <2 x i32>, <2 x i32> } %da, 1 |
| %s0 = add <2 x i32> %a0, %x |
| %s1 = add <2 x i32> %a1, %x |
| %r = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %s0, <2 x i32> %s1) |
| ret <4 x i32> %r |
| } |
| |
| define <4 x i32> @deinterleave2_extract_with_unfolded_user(<4 x i32> %a, ptr %p) { |
| ; CHECK-LABEL: define <4 x i32> @deinterleave2_extract_with_unfolded_user( |
| ; CHECK-SAME: <4 x i32> [[A:%.*]], ptr [[P:%.*]]) { |
| ; CHECK-NEXT: [[D:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> [[A]]) |
| ; CHECK-NEXT: [[F0:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[D]], 0 |
| ; CHECK-NEXT: store <2 x i32> [[F0]], ptr [[P]], align 8 |
| ; CHECK-NEXT: ret <4 x i32> [[A]] |
| ; |
| %d = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %a) |
| %f0 = extractvalue { <2 x i32>, <2 x i32> } %d, 0 |
| %f1 = extractvalue { <2 x i32>, <2 x i32> } %d, 1 |
| %r = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %f0, <2 x i32> %f1) |
| store <2 x i32> %f0, ptr %p |
| ret <4 x i32> %r |
| } |
| |
| define <4 x i32> @deinterleave2_extracts_feed_two_interleaves(<4 x i32> %a) { |
| ; CHECK-LABEL: define <4 x i32> @deinterleave2_extracts_feed_two_interleaves( |
| ; CHECK-SAME: <4 x i32> [[A:%.*]]) { |
| ; CHECK-NEXT: [[R1:%.*]] = add <4 x i32> [[A]], splat (i32 1) |
| ; CHECK-NEXT: [[R2:%.*]] = sub <4 x i32> [[A]], splat (i32 1) |
| ; CHECK-NEXT: [[R:%.*]] = xor <4 x i32> [[R1]], [[R2]] |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %da = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %a) |
| %a0 = extractvalue { <2 x i32>, <2 x i32> } %da, 0 |
| %a1 = extractvalue { <2 x i32>, <2 x i32> } %da, 1 |
| %s0 = add <2 x i32> %a0, splat (i32 1) |
| %s1 = add <2 x i32> %a1, splat (i32 1) |
| %r1 = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %s0, <2 x i32> %s1) |
| %t0 = sub <2 x i32> %a0, splat (i32 1) |
| %t1 = sub <2 x i32> %a1, splat (i32 1) |
| %r2 = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %t0, <2 x i32> %t1) |
| %r = xor <4 x i32> %r1, %r2 |
| ret <4 x i32> %r |
| } |
| |
| define <4 x float> @deinterleave2_fabs_nnan(<4 x float> %v) { |
| ; CHECK-LABEL: define <4 x float> @deinterleave2_fabs_nnan( |
| ; CHECK-SAME: <4 x float> [[V:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call nnan <4 x float> @llvm.fabs.v4f32(<4 x float> [[V]]) |
| ; CHECK-NEXT: ret <4 x float> [[R]] |
| ; |
| %d = call { <2 x float>, <2 x float> } @llvm.vector.deinterleave2.v4f32(<4 x float> %v) |
| %f0 = extractvalue { <2 x float>, <2 x float> } %d, 0 |
| %f1 = extractvalue { <2 x float>, <2 x float> } %d, 1 |
| %u0 = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %f0) |
| %u1 = call nnan <2 x float> @llvm.fabs.v2f32(<2 x float> %f1) |
| %r = call <4 x float> @llvm.vector.interleave2.v4f32(<2 x float> %u0, <2 x float> %u1) |
| ret <4 x float> %r |
| } |
| |
| define <4 x float> @deinterleave2_fabs_mismatched_fmf(<4 x float> %v) { |
| ; CHECK-LABEL: define <4 x float> @deinterleave2_fabs_mismatched_fmf( |
| ; CHECK-SAME: <4 x float> [[V:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call ninf <4 x float> @llvm.fabs.v4f32(<4 x float> [[V]]) |
| ; CHECK-NEXT: ret <4 x float> [[R]] |
| ; |
| %d = call { <2 x float>, <2 x float> } @llvm.vector.deinterleave2.v4f32(<4 x float> %v) |
| %f0 = extractvalue { <2 x float>, <2 x float> } %d, 0 |
| %f1 = extractvalue { <2 x float>, <2 x float> } %d, 1 |
| %u0 = call nnan ninf <2 x float> @llvm.fabs.v2f32(<2 x float> %f0) |
| %u1 = call ninf nsz <2 x float> @llvm.fabs.v2f32(<2 x float> %f1) |
| %r = call <4 x float> @llvm.vector.interleave2.v4f32(<2 x float> %u0, <2 x float> %u1) |
| ret <4 x float> %r |
| } |
| |
| define <8 x i32> @two_deinterleave2_smax(<8 x i32> %a, <8 x i32> %b) { |
| ; CHECK-LABEL: define <8 x i32> @two_deinterleave2_smax( |
| ; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i32> @llvm.smax.v8i32(<8 x i32> [[A]], <8 x i32> [[B]]) |
| ; CHECK-NEXT: ret <8 x i32> [[R]] |
| ; |
| %da = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %a) |
| %a0 = extractvalue { <4 x i32>, <4 x i32> } %da, 0 |
| %a1 = extractvalue { <4 x i32>, <4 x i32> } %da, 1 |
| %db = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %b) |
| %b0 = extractvalue { <4 x i32>, <4 x i32> } %db, 0 |
| %b1 = extractvalue { <4 x i32>, <4 x i32> } %db, 1 |
| %m0 = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a0, <4 x i32> %b0) |
| %m1 = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a1, <4 x i32> %b1) |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %m0, <4 x i32> %m1) |
| ret <8 x i32> %r |
| } |
| |
| define <vscale x 4 x double> @two_deinterleave2_fma_splat(<vscale x 4 x double> %a, <vscale x 4 x double> %b) { |
| ; CHECK-LABEL: define <vscale x 4 x double> @two_deinterleave2_fma_splat( |
| ; CHECK-SAME: <vscale x 4 x double> [[A:%.*]], <vscale x 4 x double> [[B:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call contract <vscale x 4 x double> @llvm.fma.nxv4f64(<vscale x 4 x double> [[A]], <vscale x 4 x double> [[B]], <vscale x 4 x double> splat (double 1.000000e+00)) |
| ; CHECK-NEXT: ret <vscale x 4 x double> [[R]] |
| ; |
| %da = call { <vscale x 2 x double>, <vscale x 2 x double> } @llvm.vector.deinterleave2.nxv4f64(<vscale x 4 x double> %a) |
| %a0 = extractvalue { <vscale x 2 x double>, <vscale x 2 x double> } %da, 0 |
| %a1 = extractvalue { <vscale x 2 x double>, <vscale x 2 x double> } %da, 1 |
| %db = call { <vscale x 2 x double>, <vscale x 2 x double> } @llvm.vector.deinterleave2.nxv4f64(<vscale x 4 x double> %b) |
| %b0 = extractvalue { <vscale x 2 x double>, <vscale x 2 x double> } %db, 0 |
| %b1 = extractvalue { <vscale x 2 x double>, <vscale x 2 x double> } %db, 1 |
| %m0 = call contract <vscale x 2 x double> @llvm.fma.nxv2f64(<vscale x 2 x double> %a0, <vscale x 2 x double> %b0, <vscale x 2 x double> splat (double 1.0)) |
| %m1 = call contract <vscale x 2 x double> @llvm.fma.nxv2f64(<vscale x 2 x double> %a1, <vscale x 2 x double> %b1, <vscale x 2 x double> splat (double 1.0)) |
| %r = call <vscale x 4 x double> @llvm.vector.interleave2.nxv4f64(<vscale x 2 x double> %m0, <vscale x 2 x double> %m1) |
| ret <vscale x 4 x double> %r |
| } |
| |
| define <8 x i16> @deinterleave2_umin_scalar_splat(<8 x i16> %v, i16 %s) { |
| ; CHECK-LABEL: define <8 x i16> @deinterleave2_umin_scalar_splat( |
| ; CHECK-SAME: <8 x i16> [[V:%.*]], i16 [[S:%.*]]) { |
| ; CHECK-NEXT: [[DOTSPLATINSERT:%.*]] = insertelement <8 x i16> poison, i16 [[S]], i64 0 |
| ; CHECK-NEXT: [[DOTSPLAT:%.*]] = shufflevector <8 x i16> [[DOTSPLATINSERT]], <8 x i16> poison, <8 x i32> zeroinitializer |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i16> @llvm.umin.v8i16(<8 x i16> [[V]], <8 x i16> [[DOTSPLAT]]) |
| ; CHECK-NEXT: ret <8 x i16> [[R]] |
| ; |
| %s.ins = insertelement <4 x i16> poison, i16 %s, i64 0 |
| %s.splat = shufflevector <4 x i16> %s.ins, <4 x i16> poison, <4 x i32> zeroinitializer |
| %d = call { <4 x i16>, <4 x i16> } @llvm.vector.deinterleave2.v8i16(<8 x i16> %v) |
| %f0 = extractvalue { <4 x i16>, <4 x i16> } %d, 0 |
| %f1 = extractvalue { <4 x i16>, <4 x i16> } %d, 1 |
| %u0 = call <4 x i16> @llvm.umin.v4i16(<4 x i16> %f0, <4 x i16> %s.splat) |
| %u1 = call <4 x i16> @llvm.umin.v4i16(<4 x i16> %f1, <4 x i16> %s.splat) |
| %r = call <8 x i16> @llvm.vector.interleave2.v8i16(<4 x i16> %u0, <4 x i16> %u1) |
| ret <8 x i16> %r |
| } |
| |
| define <4 x float> @deinterleave2_powi_same_exponent(<4 x float> %v, i32 %n) { |
| ; CHECK-LABEL: define <4 x float> @deinterleave2_powi_same_exponent( |
| ; CHECK-SAME: <4 x float> [[V:%.*]], i32 [[N:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call <4 x float> @llvm.powi.v4f32.i32(<4 x float> [[V]], i32 [[N]]) |
| ; CHECK-NEXT: ret <4 x float> [[R]] |
| ; |
| %d = call { <2 x float>, <2 x float> } @llvm.vector.deinterleave2.v4f32(<4 x float> %v) |
| %f0 = extractvalue { <2 x float>, <2 x float> } %d, 0 |
| %f1 = extractvalue { <2 x float>, <2 x float> } %d, 1 |
| %u0 = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %f0, i32 %n) |
| %u1 = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %f1, i32 %n) |
| %r = call <4 x float> @llvm.vector.interleave2.v4f32(<2 x float> %u0, <2 x float> %u1) |
| ret <4 x float> %r |
| } |
| |
| define <4 x float> @negative_deinterleave2_powi_different_exponent(<4 x float> %v, i32 %n, i32 %m) { |
| ; CHECK-LABEL: define <4 x float> @negative_deinterleave2_powi_different_exponent( |
| ; CHECK-SAME: <4 x float> [[V:%.*]], i32 [[N:%.*]], i32 [[M:%.*]]) { |
| ; CHECK-NEXT: [[D:%.*]] = call { <2 x float>, <2 x float> } @llvm.vector.deinterleave2.v4f32(<4 x float> [[V]]) |
| ; CHECK-NEXT: [[F0:%.*]] = extractvalue { <2 x float>, <2 x float> } [[D]], 0 |
| ; CHECK-NEXT: [[F1:%.*]] = extractvalue { <2 x float>, <2 x float> } [[D]], 1 |
| ; CHECK-NEXT: [[U0:%.*]] = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> [[F0]], i32 [[N]]) |
| ; CHECK-NEXT: [[U1:%.*]] = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> [[F1]], i32 [[M]]) |
| ; CHECK-NEXT: [[R:%.*]] = call <4 x float> @llvm.vector.interleave2.v4f32(<2 x float> [[U0]], <2 x float> [[U1]]) |
| ; CHECK-NEXT: ret <4 x float> [[R]] |
| ; |
| %d = call { <2 x float>, <2 x float> } @llvm.vector.deinterleave2.v4f32(<4 x float> %v) |
| %f0 = extractvalue { <2 x float>, <2 x float> } %d, 0 |
| %f1 = extractvalue { <2 x float>, <2 x float> } %d, 1 |
| %u0 = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %f0, i32 %n) |
| %u1 = call <2 x float> @llvm.powi.v2f32.i32(<2 x float> %f1, i32 %m) |
| %r = call <4 x float> @llvm.vector.interleave2.v4f32(<2 x float> %u0, <2 x float> %u1) |
| ret <4 x float> %r |
| } |
| |
| define <8 x i8> @deinterleave2_ctlz_same_immarg(<8 x i8> %v) { |
| ; CHECK-LABEL: define <8 x i8> @deinterleave2_ctlz_same_immarg( |
| ; CHECK-SAME: <8 x i8> [[V:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i8> @llvm.ctlz.v8i8(<8 x i8> [[V]], i1 true) |
| ; CHECK-NEXT: ret <8 x i8> [[R]] |
| ; |
| %d = call { <4 x i8>, <4 x i8> } @llvm.vector.deinterleave2.v8i8(<8 x i8> %v) |
| %f0 = extractvalue { <4 x i8>, <4 x i8> } %d, 0 |
| %f1 = extractvalue { <4 x i8>, <4 x i8> } %d, 1 |
| %u0 = call <4 x i8> @llvm.ctlz.v4i8(<4 x i8> %f0, i1 true) |
| %u1 = call <4 x i8> @llvm.ctlz.v4i8(<4 x i8> %f1, i1 true) |
| %r = call <8 x i8> @llvm.vector.interleave2.v8i8(<4 x i8> %u0, <4 x i8> %u1) |
| ret <8 x i8> %r |
| } |
| |
| define <8 x i8> @negative_deinterleave2_ctlz_different_immarg(<8 x i8> %v) { |
| ; CHECK-LABEL: define <8 x i8> @negative_deinterleave2_ctlz_different_immarg( |
| ; CHECK-SAME: <8 x i8> [[V:%.*]]) { |
| ; CHECK-NEXT: [[D:%.*]] = call { <4 x i8>, <4 x i8> } @llvm.vector.deinterleave2.v8i8(<8 x i8> [[V]]) |
| ; CHECK-NEXT: [[F0:%.*]] = extractvalue { <4 x i8>, <4 x i8> } [[D]], 0 |
| ; CHECK-NEXT: [[F1:%.*]] = extractvalue { <4 x i8>, <4 x i8> } [[D]], 1 |
| ; CHECK-NEXT: [[U0:%.*]] = call <4 x i8> @llvm.ctlz.v4i8(<4 x i8> [[F0]], i1 true) |
| ; CHECK-NEXT: [[U1:%.*]] = call <4 x i8> @llvm.ctlz.v4i8(<4 x i8> [[F1]], i1 false) |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i8> @llvm.vector.interleave2.v8i8(<4 x i8> [[U0]], <4 x i8> [[U1]]) |
| ; CHECK-NEXT: ret <8 x i8> [[R]] |
| ; |
| %d = call { <4 x i8>, <4 x i8> } @llvm.vector.deinterleave2.v8i8(<8 x i8> %v) |
| %f0 = extractvalue { <4 x i8>, <4 x i8> } %d, 0 |
| %f1 = extractvalue { <4 x i8>, <4 x i8> } %d, 1 |
| %u0 = call <4 x i8> @llvm.ctlz.v4i8(<4 x i8> %f0, i1 true) |
| %u1 = call <4 x i8> @llvm.ctlz.v4i8(<4 x i8> %f1, i1 false) |
| %r = call <8 x i8> @llvm.vector.interleave2.v8i8(<4 x i8> %u0, <4 x i8> %u1) |
| ret <8 x i8> %r |
| } |
| |
| define <8 x i32> @negative_two_deinterleave2_smax_smin(<8 x i32> %a, <8 x i32> %b) { |
| ; CHECK-LABEL: define <8 x i32> @negative_two_deinterleave2_smax_smin( |
| ; CHECK-SAME: <8 x i32> [[A:%.*]], <8 x i32> [[B:%.*]]) { |
| ; CHECK-NEXT: [[DA:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[A]]) |
| ; CHECK-NEXT: [[A0:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DA]], 0 |
| ; CHECK-NEXT: [[A1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DA]], 1 |
| ; CHECK-NEXT: [[DB:%.*]] = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> [[B]]) |
| ; CHECK-NEXT: [[B0:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DB]], 0 |
| ; CHECK-NEXT: [[B1:%.*]] = extractvalue { <4 x i32>, <4 x i32> } [[DB]], 1 |
| ; CHECK-NEXT: [[M0:%.*]] = call <4 x i32> @llvm.smax.v4i32(<4 x i32> [[A0]], <4 x i32> [[B0]]) |
| ; CHECK-NEXT: [[M1:%.*]] = call <4 x i32> @llvm.smin.v4i32(<4 x i32> [[A1]], <4 x i32> [[B1]]) |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> [[M0]], <4 x i32> [[M1]]) |
| ; CHECK-NEXT: ret <8 x i32> [[R]] |
| ; |
| %da = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %a) |
| %a0 = extractvalue { <4 x i32>, <4 x i32> } %da, 0 |
| %a1 = extractvalue { <4 x i32>, <4 x i32> } %da, 1 |
| %db = call { <4 x i32>, <4 x i32> } @llvm.vector.deinterleave2.v8i32(<8 x i32> %b) |
| %b0 = extractvalue { <4 x i32>, <4 x i32> } %db, 0 |
| %b1 = extractvalue { <4 x i32>, <4 x i32> } %db, 1 |
| %m0 = call <4 x i32> @llvm.smax.v4i32(<4 x i32> %a0, <4 x i32> %b0) |
| %m1 = call <4 x i32> @llvm.smin.v4i32(<4 x i32> %a1, <4 x i32> %b1) |
| %r = call <8 x i32> @llvm.vector.interleave2.v8i32(<4 x i32> %m0, <4 x i32> %m1) |
| ret <8 x i32> %r |
| } |
| |
| define <4 x i32> @negative_deinterleave2_vector_reverse(<4 x i32> %v) { |
| ; CHECK-LABEL: define <4 x i32> @negative_deinterleave2_vector_reverse( |
| ; CHECK-SAME: <4 x i32> [[V:%.*]]) { |
| ; CHECK-NEXT: [[D:%.*]] = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> [[V]]) |
| ; CHECK-NEXT: [[F0:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[D]], 0 |
| ; CHECK-NEXT: [[F1:%.*]] = extractvalue { <2 x i32>, <2 x i32> } [[D]], 1 |
| ; CHECK-NEXT: [[U0:%.*]] = call <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32> [[F0]]) |
| ; CHECK-NEXT: [[U1:%.*]] = call <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32> [[F1]]) |
| ; CHECK-NEXT: [[R:%.*]] = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> [[U0]], <2 x i32> [[U1]]) |
| ; CHECK-NEXT: ret <4 x i32> [[R]] |
| ; |
| %d = call { <2 x i32>, <2 x i32> } @llvm.vector.deinterleave2.v4i32(<4 x i32> %v) |
| %f0 = extractvalue { <2 x i32>, <2 x i32> } %d, 0 |
| %f1 = extractvalue { <2 x i32>, <2 x i32> } %d, 1 |
| %u0 = call <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32> %f0) |
| %u1 = call <2 x i32> @llvm.vector.reverse.v2i32(<2 x i32> %f1) |
| %r = call <4 x i32> @llvm.vector.interleave2.v4i32(<2 x i32> %u0, <2 x i32> %u1) |
| ret <4 x i32> %r |
| } |
| |
| define <vscale x 12 x i16> @two_deinterleave3_abs_mul_sat(<vscale x 12 x i16> %a, <vscale x 12 x i16> %b) { |
| ; CHECK-LABEL: define <vscale x 12 x i16> @two_deinterleave3_abs_mul_sat( |
| ; CHECK-SAME: <vscale x 12 x i16> [[A:%.*]], <vscale x 12 x i16> [[B:%.*]]) { |
| ; CHECK-NEXT: [[TMP1:%.*]] = call <vscale x 12 x i16> @llvm.abs.nxv12i16(<vscale x 12 x i16> [[A]], i1 false) |
| ; CHECK-NEXT: [[TMP2:%.*]] = mul nsw <vscale x 12 x i16> [[TMP1]], [[B]] |
| ; CHECK-NEXT: [[R:%.*]] = call <vscale x 12 x i16> @llvm.sadd.sat.nxv12i16(<vscale x 12 x i16> [[TMP2]], <vscale x 12 x i16> splat (i16 7)) |
| ; CHECK-NEXT: ret <vscale x 12 x i16> [[R]] |
| ; |
| %da = call { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } @llvm.vector.deinterleave3.nxv12i16(<vscale x 12 x i16> %a) |
| %a0 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } %da, 0 |
| %a1 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } %da, 1 |
| %a2 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } %da, 2 |
| %db = call { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } @llvm.vector.deinterleave3.nxv12i16(<vscale x 12 x i16> %b) |
| %b0 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } %db, 0 |
| %b1 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } %db, 1 |
| %b2 = extractvalue { <vscale x 4 x i16>, <vscale x 4 x i16>, <vscale x 4 x i16> } %db, 2 |
| %abs0 = call <vscale x 4 x i16> @llvm.abs.nxv4i16(<vscale x 4 x i16> %a0, i1 false) |
| %abs1 = call <vscale x 4 x i16> @llvm.abs.nxv4i16(<vscale x 4 x i16> %a1, i1 false) |
| %abs2 = call <vscale x 4 x i16> @llvm.abs.nxv4i16(<vscale x 4 x i16> %a2, i1 false) |
| %m0 = mul nsw <vscale x 4 x i16> %abs0, %b0 |
| %m1 = mul nsw <vscale x 4 x i16> %abs1, %b1 |
| %m2 = mul nsw <vscale x 4 x i16> %abs2, %b2 |
| %s0 = call <vscale x 4 x i16> @llvm.sadd.sat.nxv4i16(<vscale x 4 x i16> %m0, <vscale x 4 x i16> splat (i16 7)) |
| %s1 = call <vscale x 4 x i16> @llvm.sadd.sat.nxv4i16(<vscale x 4 x i16> %m1, <vscale x 4 x i16> splat (i16 7)) |
| %s2 = call <vscale x 4 x i16> @llvm.sadd.sat.nxv4i16(<vscale x 4 x i16> %m2, <vscale x 4 x i16> splat (i16 7)) |
| %r = call <vscale x 12 x i16> @llvm.vector.interleave3.nxv12i16(<vscale x 4 x i16> %s0, <vscale x 4 x i16> %s1, <vscale x 4 x i16> %s2) |
| ret <vscale x 12 x i16> %r |
| } |
| |
| define <8 x i1> @deinterleave2_is_fpclass(<8 x float> %v) { |
| ; CHECK-LABEL: define <8 x i1> @deinterleave2_is_fpclass( |
| ; CHECK-SAME: <8 x float> [[V:%.*]]) { |
| ; CHECK-NEXT: [[R:%.*]] = call <8 x i1> @llvm.is.fpclass.v8f32(<8 x float> [[V]], /* (nan) */ i32 3) |
| ; CHECK-NEXT: ret <8 x i1> [[R]] |
| ; |
| %d = call { <4 x float>, <4 x float> } @llvm.vector.deinterleave2.v8f32(<8 x float> %v) |
| %f0 = extractvalue { <4 x float>, <4 x float> } %d, 0 |
| %f1 = extractvalue { <4 x float>, <4 x float> } %d, 1 |
| %c0 = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f0, i32 3) |
| %c1 = call <4 x i1> @llvm.is.fpclass.v4f32(<4 x float> %f1, i32 3) |
| %r = call <8 x i1> @llvm.vector.interleave2.v8i1(<4 x i1> %c0, <4 x i1> %c1) |
| ret <8 x i1> %r |
| } |