1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64 < %s | FileCheck %s 3 4define <8 x i16> @not_not_trunc_concat(<4 x i32> %x, <4 x i32> %y) { 5; CHECK-LABEL: not_not_trunc_concat: 6; CHECK: // %bb.0: 7; CHECK-NEXT: uzp1 v0.8h, v0.8h, v1.8h 8; CHECK-NEXT: mvn v0.16b, v0.16b 9; CHECK-NEXT: ret 10 %notx = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 11 %trnx = trunc <4 x i32> %notx to <4 x i16> 12 %noty = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1> 13 %trny = trunc <4 x i32> %noty to <4 x i16> 14 %r = shufflevector <4 x i16> %trnx, <4 x i16> %trny, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 15 ret <8 x i16> %r 16} 17 18; Chains of concat -> truncate -> negate should flatten out to a single negate. 19define <16 x i8> @not_not_trunc_concat_chain(<4 x i32> %a, <4 x i32> %b, <4 x i32> %x, <4 x i32> %y) { 20; CHECK-LABEL: not_not_trunc_concat_chain: 21; CHECK: // %bb.0: 22; CHECK-NEXT: uzp1 v2.8h, v2.8h, v3.8h 23; CHECK-NEXT: uzp1 v0.8h, v0.8h, v1.8h 24; CHECK-NEXT: uzp1 v0.16b, v0.16b, v2.16b 25; CHECK-NEXT: mvn v0.16b, v0.16b 26; CHECK-NEXT: ret 27 %nota = xor <4 x i32> %a, <i32 -1, i32 -1, i32 -1, i32 -1> 28 %trna = trunc <4 x i32> %nota to <4 x i16> 29 %notb = xor <4 x i32> %b, <i32 -1, i32 -1, i32 -1, i32 -1> 30 %trnb = trunc <4 x i32> %notb to <4 x i16> 31 %concat_a = shufflevector <4 x i16> %trna, <4 x i16> %trnb, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 32 %trun_concat_a = trunc <8 x i16> %concat_a to <8 x i8> 33 %notx = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 34 %trnx = trunc <4 x i32> %notx to <4 x i16> 35 %noty = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1> 36 %trny = trunc <4 x i32> %noty to <4 x i16> 37 %concat_b = shufflevector <4 x i16> %trnx, <4 x i16> %trny, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 38 %trun_concat_b = trunc <8 x i16> %concat_b to <8 x i8> 39 %r = shufflevector <8 x i8> %trun_concat_a, <8 x i8> %trun_concat_b, <16 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7, i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15> 40 ret <16 x i8> %r 41} 42 43; Combine should not fire here, otherwise slightly worse code will be emitted. 44define <8 x i16> @not_not_trunc_concat_multiple_uses(<4 x i32> %x, <4 x i32> %y) { 45; CHECK-LABEL: not_not_trunc_concat_multiple_uses: 46; CHECK: // %bb.0: 47; CHECK-NEXT: xtn v0.4h, v0.4s 48; CHECK-NEXT: xtn v1.4h, v1.4s 49; CHECK-NEXT: mvn v0.8b, v0.8b 50; CHECK-NEXT: mvn v1.8b, v1.8b 51; CHECK-NEXT: add v2.4h, v0.4h, v1.4h 52; CHECK-NEXT: mov v0.d[1], v1.d[0] 53; CHECK-NEXT: mov v2.d[1], v2.d[0] 54; CHECK-NEXT: add v0.8h, v0.8h, v2.8h 55; CHECK-NEXT: ret 56 %notx = xor <4 x i32> %x, <i32 -1, i32 -1, i32 -1, i32 -1> 57 %trnx = trunc <4 x i32> %notx to <4 x i16> 58 %noty = xor <4 x i32> %y, <i32 -1, i32 -1, i32 -1, i32 -1> 59 %trny = trunc <4 x i32> %noty to <4 x i16> 60 %concat = shufflevector <4 x i16> %trnx, <4 x i16> %trny, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 61 %add = add <4 x i16> %trnx, %trny 62 %extend_add = shufflevector <4 x i16> %add, <4 x i16> %add, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 63 %r = add <8 x i16> %concat, %extend_add 64 ret <8 x i16> %r 65 66} 67 68