1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4 2; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=sse2 | FileCheck %s --check-prefixes=CHECK,SSE 3; RUN: opt < %s -passes=vector-combine -S -mtriple=x86_64-- -mattr=avx2 | FileCheck %s --check-prefixes=CHECK,AVX 4 5; standard vector concatenations 6 7define <16 x i32> @concat_zext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) { 8; CHECK-LABEL: define <16 x i32> @concat_zext_v8i16_v16i32( 9; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0:[0-9]+]] { 10; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <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> 11; CHECK-NEXT: [[R:%.*]] = zext <16 x i16> [[TMP1]] to <16 x i32> 12; CHECK-NEXT: ret <16 x i32> [[R]] 13; 14 %x0 = zext <8 x i16> %a0 to <8 x i32> 15 %x1 = zext <8 x i16> %a1 to <8 x i32> 16 %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <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> 17 ret <16 x i32> %r 18} 19 20define <16 x i32> @concat_zext_nneg_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) { 21; CHECK-LABEL: define <16 x i32> @concat_zext_nneg_v8i16_v16i32( 22; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 23; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <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> 24; CHECK-NEXT: [[R:%.*]] = zext nneg <16 x i16> [[TMP1]] to <16 x i32> 25; CHECK-NEXT: ret <16 x i32> [[R]] 26; 27 %x0 = zext nneg <8 x i16> %a0 to <8 x i32> 28 %x1 = zext nneg <8 x i16> %a1 to <8 x i32> 29 %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <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> 30 ret <16 x i32> %r 31} 32 33define <16 x i32> @concat_sext_zext_nneg_v8i16_v8i32(<8 x i16> %a0, <8 x i16> %a1) { 34; SSE-LABEL: define <16 x i32> @concat_sext_zext_nneg_v8i16_v8i32( 35; SSE-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 36; SSE-NEXT: [[X0:%.*]] = sext <8 x i16> [[A0]] to <8 x i32> 37; SSE-NEXT: [[X1:%.*]] = zext nneg <8 x i16> [[A1]] to <8 x i32> 38; SSE-NEXT: [[R:%.*]] = shufflevector <8 x i32> [[X0]], <8 x i32> [[X1]], <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> 39; SSE-NEXT: ret <16 x i32> [[R]] 40; 41; AVX-LABEL: define <16 x i32> @concat_sext_zext_nneg_v8i16_v8i32( 42; AVX-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 43; AVX-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <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> 44; AVX-NEXT: [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32> 45; AVX-NEXT: ret <16 x i32> [[R]] 46; 47 %x0 = sext <8 x i16> %a0 to <8 x i32> 48 %x1 = zext nneg <8 x i16> %a1 to <8 x i32> 49 %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <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> 50 ret <16 x i32> %r 51} 52 53define <16 x i32> @concat_sext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) { 54; CHECK-LABEL: define <16 x i32> @concat_sext_v8i16_v16i32( 55; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 56; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <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> 57; CHECK-NEXT: [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32> 58; CHECK-NEXT: ret <16 x i32> [[R]] 59; 60 %x0 = sext <8 x i16> %a0 to <8 x i32> 61 %x1 = sext <8 x i16> %a1 to <8 x i32> 62 %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <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> 63 ret <16 x i32> %r 64} 65 66define <8 x i32> @concat_sext_v4i1_v8i32(<4 x i1> %a0, <4 x i1> %a1) { 67; SSE-LABEL: define <8 x i32> @concat_sext_v4i1_v8i32( 68; SSE-SAME: <4 x i1> [[A0:%.*]], <4 x i1> [[A1:%.*]]) #[[ATTR0]] { 69; SSE-NEXT: [[X0:%.*]] = sext <4 x i1> [[A0]] to <4 x i32> 70; SSE-NEXT: [[X1:%.*]] = sext <4 x i1> [[A1]] to <4 x i32> 71; SSE-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[X0]], <4 x i32> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 72; SSE-NEXT: ret <8 x i32> [[R]] 73; 74; AVX-LABEL: define <8 x i32> @concat_sext_v4i1_v8i32( 75; AVX-SAME: <4 x i1> [[A0:%.*]], <4 x i1> [[A1:%.*]]) #[[ATTR0]] { 76; AVX-NEXT: [[TMP1:%.*]] = shufflevector <4 x i1> [[A0]], <4 x i1> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 77; AVX-NEXT: [[R:%.*]] = sext <8 x i1> [[TMP1]] to <8 x i32> 78; AVX-NEXT: ret <8 x i32> [[R]] 79; 80 %x0 = sext <4 x i1> %a0 to <4 x i32> 81 %x1 = sext <4 x i1> %a1 to <4 x i32> 82 %r = shufflevector <4 x i32> %x0, <4 x i32> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 83 ret <8 x i32> %r 84} 85 86define <8 x i16> @concat_trunc_v4i32_v8i16(<4 x i32> %a0, <4 x i32> %a1) { 87; CHECK-LABEL: define <8 x i16> @concat_trunc_v4i32_v8i16( 88; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] { 89; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 90; CHECK-NEXT: [[R:%.*]] = trunc <8 x i32> [[TMP1]] to <8 x i16> 91; CHECK-NEXT: ret <8 x i16> [[R]] 92; 93 %x0 = trunc <4 x i32> %a0 to <4 x i16> 94 %x1 = trunc <4 x i32> %a1 to <4 x i16> 95 %r = shufflevector <4 x i16> %x0, <4 x i16> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 96 ret <8 x i16> %r 97} 98 99define <8 x ptr> @concat_inttoptr_v4i32_v8iptr(<4 x i32> %a0, <4 x i32> %a1) { 100; SSE-LABEL: define <8 x ptr> @concat_inttoptr_v4i32_v8iptr( 101; SSE-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] { 102; SSE-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 103; SSE-NEXT: [[R:%.*]] = inttoptr <8 x i32> [[TMP1]] to <8 x ptr> 104; SSE-NEXT: ret <8 x ptr> [[R]] 105; 106; AVX-LABEL: define <8 x ptr> @concat_inttoptr_v4i32_v8iptr( 107; AVX-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] { 108; AVX-NEXT: [[X0:%.*]] = inttoptr <4 x i32> [[A0]] to <4 x ptr> 109; AVX-NEXT: [[X1:%.*]] = inttoptr <4 x i32> [[A1]] to <4 x ptr> 110; AVX-NEXT: [[R:%.*]] = shufflevector <4 x ptr> [[X0]], <4 x ptr> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 111; AVX-NEXT: ret <8 x ptr> [[R]] 112; 113 %x0 = inttoptr <4 x i32> %a0 to <4 x ptr> 114 %x1 = inttoptr <4 x i32> %a1 to <4 x ptr> 115 %r = shufflevector <4 x ptr> %x0, <4 x ptr> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 116 ret <8 x ptr> %r 117} 118 119define <16 x i64> @concat_ptrtoint_v8i16_v16i32(<8 x ptr> %a0, <8 x ptr> %a1) { 120; CHECK-LABEL: define <16 x i64> @concat_ptrtoint_v8i16_v16i32( 121; CHECK-SAME: <8 x ptr> [[A0:%.*]], <8 x ptr> [[A1:%.*]]) #[[ATTR0]] { 122; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x ptr> [[A0]], <8 x ptr> [[A1]], <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> 123; CHECK-NEXT: [[R:%.*]] = ptrtoint <16 x ptr> [[TMP1]] to <16 x i64> 124; CHECK-NEXT: ret <16 x i64> [[R]] 125; 126 %x0 = ptrtoint <8 x ptr> %a0 to <8 x i64> 127 %x1 = ptrtoint <8 x ptr> %a1 to <8 x i64> 128 %r = shufflevector <8 x i64> %x0, <8 x i64> %x1, <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> 129 ret <16 x i64> %r 130} 131 132define <8 x double> @concat_fpext_v4f32_v8f64(<4 x float> %a0, <4 x float> %a1) { 133; SSE-LABEL: define <8 x double> @concat_fpext_v4f32_v8f64( 134; SSE-SAME: <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]) #[[ATTR0]] { 135; SSE-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[A0]], <4 x float> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 136; SSE-NEXT: [[R:%.*]] = fpext <8 x float> [[TMP1]] to <8 x double> 137; SSE-NEXT: ret <8 x double> [[R]] 138; 139; AVX-LABEL: define <8 x double> @concat_fpext_v4f32_v8f64( 140; AVX-SAME: <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]) #[[ATTR0]] { 141; AVX-NEXT: [[X0:%.*]] = fpext <4 x float> [[A0]] to <4 x double> 142; AVX-NEXT: [[X1:%.*]] = fpext <4 x float> [[A1]] to <4 x double> 143; AVX-NEXT: [[R:%.*]] = shufflevector <4 x double> [[X0]], <4 x double> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 144; AVX-NEXT: ret <8 x double> [[R]] 145; 146 %x0 = fpext <4 x float> %a0 to <4 x double> 147 %x1 = fpext <4 x float> %a1 to <4 x double> 148 %r = shufflevector <4 x double> %x0, <4 x double> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 149 ret <8 x double> %r 150} 151 152define <16 x float> @concat_fptrunc_v8f64_v16f32(<8 x double> %a0, <8 x double> %a1) { 153; CHECK-LABEL: define <16 x float> @concat_fptrunc_v8f64_v16f32( 154; CHECK-SAME: <8 x double> [[A0:%.*]], <8 x double> [[A1:%.*]]) #[[ATTR0]] { 155; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x double> [[A0]], <8 x double> [[A1]], <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> 156; CHECK-NEXT: [[R:%.*]] = fptrunc <16 x double> [[TMP1]] to <16 x float> 157; CHECK-NEXT: ret <16 x float> [[R]] 158; 159 %x0 = fptrunc <8 x double> %a0 to <8 x float> 160 %x1 = fptrunc <8 x double> %a1 to <8 x float> 161 %r = shufflevector <8 x float> %x0, <8 x float> %x1, <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> 162 ret <16 x float> %r 163} 164 165; commuted vector concatenation 166 167define <16 x i32> @rconcat_sext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) { 168; SSE-LABEL: define <16 x i32> @rconcat_sext_v8i16_v16i32( 169; SSE-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 170; SSE-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A1]], <8 x i16> [[A0]], <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> 171; SSE-NEXT: [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32> 172; SSE-NEXT: ret <16 x i32> [[R]] 173; 174; AVX-LABEL: define <16 x i32> @rconcat_sext_v8i16_v16i32( 175; AVX-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 176; AVX-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 177; AVX-NEXT: [[R:%.*]] = sext <16 x i16> [[TMP1]] to <16 x i32> 178; AVX-NEXT: ret <16 x i32> [[R]] 179; 180 %x0 = sext <8 x i16> %a0 to <8 x i32> 181 %x1 = sext <8 x i16> %a1 to <8 x i32> 182 %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <16 x i32> <i32 8, i32 9, i32 10, i32 11, i32 12, i32 13, i32 14, i32 15, i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 183 ret <16 x i32> %r 184} 185 186; interleaved shuffle 187 188define <8 x double> @interleave_fpext_v4f32_v8f64(<4 x float> %a0, <4 x float> %a1) { 189; CHECK-LABEL: define <8 x double> @interleave_fpext_v4f32_v8f64( 190; CHECK-SAME: <4 x float> [[A0:%.*]], <4 x float> [[A1:%.*]]) #[[ATTR0]] { 191; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x float> [[A0]], <4 x float> [[A1]], <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7> 192; CHECK-NEXT: [[R:%.*]] = fpext <8 x float> [[TMP1]] to <8 x double> 193; CHECK-NEXT: ret <8 x double> [[R]] 194; 195 %x0 = fpext <4 x float> %a0 to <4 x double> 196 %x1 = fpext <4 x float> %a1 to <4 x double> 197 %r = shufflevector <4 x double> %x0, <4 x double> %x1, <8 x i32> <i32 0, i32 4, i32 1, i32 5, i32 2, i32 6, i32 3, i32 7> 198 ret <8 x double> %r 199} 200 201; bitcasts (same element count) 202 203define <8 x float> @concat_bitcast_v4i32_v8f32(<4 x i32> %a0, <4 x i32> %a1) { 204; CHECK-LABEL: define <8 x float> @concat_bitcast_v4i32_v8f32( 205; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] { 206; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 207; CHECK-NEXT: [[R:%.*]] = bitcast <8 x i32> [[TMP1]] to <8 x float> 208; CHECK-NEXT: ret <8 x float> [[R]] 209; 210 %x0 = bitcast <4 x i32> %a0 to <4 x float> 211 %x1 = bitcast <4 x i32> %a1 to <4 x float> 212 %r = shufflevector <4 x float> %x0, <4 x float> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 213 ret <8 x float> %r 214} 215 216; bitcasts (lower element count) 217 218define <4 x double> @concat_bitcast_v8i16_v4f64(<8 x i16> %a0, <8 x i16> %a1) { 219; CHECK-LABEL: define <4 x double> @concat_bitcast_v8i16_v4f64( 220; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 221; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <8 x i16> [[A0]], <8 x i16> [[A1]], <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> 222; CHECK-NEXT: [[R:%.*]] = bitcast <16 x i16> [[TMP1]] to <4 x double> 223; CHECK-NEXT: ret <4 x double> [[R]] 224; 225 %x0 = bitcast <8 x i16> %a0 to <2 x double> 226 %x1 = bitcast <8 x i16> %a1 to <2 x double> 227 %r = shufflevector <2 x double> %x0, <2 x double> %x1, <4 x i32> <i32 0, i32 1, i32 2, i32 3> 228 ret <4 x double> %r 229} 230 231; bitcasts (higher element count) 232 233define <16 x i16> @concat_bitcast_v4i32_v16i16(<4 x i32> %a0, <4 x i32> %a1) { 234; CHECK-LABEL: define <16 x i16> @concat_bitcast_v4i32_v16i16( 235; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] { 236; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 237; CHECK-NEXT: [[R:%.*]] = bitcast <8 x i32> [[TMP1]] to <16 x i16> 238; CHECK-NEXT: ret <16 x i16> [[R]] 239; 240 %x0 = bitcast <4 x i32> %a0 to <8 x i16> 241 %x1 = bitcast <4 x i32> %a1 to <8 x i16> 242 %r = shufflevector <8 x i16> %x0, <8 x i16> %x1, <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> 243 ret <16 x i16> %r 244} 245 246; multiuse - ensure cost of any duplicated casts are worth it 247 248define <8 x i16> @concat_trunc_v4i32_v8i16_multiuse(<4 x i32> %a0, <4 x i32> %a1, ptr %a2) { 249; CHECK-LABEL: define <8 x i16> @concat_trunc_v4i32_v8i16_multiuse( 250; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]], ptr [[A2:%.*]]) #[[ATTR0]] { 251; CHECK-NEXT: [[X0:%.*]] = trunc <4 x i32> [[A0]] to <4 x i16> 252; CHECK-NEXT: [[TMP1:%.*]] = shufflevector <4 x i32> [[A0]], <4 x i32> [[A1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 253; CHECK-NEXT: [[R:%.*]] = trunc <8 x i32> [[TMP1]] to <8 x i16> 254; CHECK-NEXT: store <4 x i16> [[X0]], ptr [[A2]], align 8 255; CHECK-NEXT: ret <8 x i16> [[R]] 256; 257 %x0 = trunc <4 x i32> %a0 to <4 x i16> 258 %x1 = trunc <4 x i32> %a1 to <4 x i16> 259 %r = shufflevector <4 x i16> %x0, <4 x i16> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 260 store <4 x i16> %x0, ptr %a2 261 ret <8 x i16> %r 262} 263 264; negative - multiuse - ensure cost of any duplicated casts are worth it 265 266define <16 x i8> @concat_trunc_v8i64_v16i8_multiuse(<8 x i64> %a0, <8 x i64> %a1, ptr %a2) { 267; CHECK-LABEL: define <16 x i8> @concat_trunc_v8i64_v16i8_multiuse( 268; CHECK-SAME: <8 x i64> [[A0:%.*]], <8 x i64> [[A1:%.*]], ptr [[A2:%.*]]) #[[ATTR0]] { 269; CHECK-NEXT: [[X0:%.*]] = trunc <8 x i64> [[A0]] to <8 x i8> 270; CHECK-NEXT: [[X1:%.*]] = trunc <8 x i64> [[A1]] to <8 x i8> 271; CHECK-NEXT: [[R:%.*]] = shufflevector <8 x i8> [[X0]], <8 x i8> [[X1]], <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 4, i32 15> 272; CHECK-NEXT: store <8 x i8> [[X0]], ptr [[A2]], align 8 273; CHECK-NEXT: ret <16 x i8> [[R]] 274; 275 %x0 = trunc <8 x i64> %a0 to <8 x i8> 276 %x1 = trunc <8 x i64> %a1 to <8 x i8> 277 %r = shufflevector <8 x i8> %x0, <8 x i8> %x1, <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 4, i32 15> 278 store <8 x i8> %x0, ptr %a2 279 ret <16 x i8> %r 280} 281 282; negative - bitcasts (unscalable higher element count) 283 284define <16 x i16> @revpair_bitcast_v4i32_v16i16(<4 x i32> %a0, <4 x i32> %a1) { 285; CHECK-LABEL: define <16 x i16> @revpair_bitcast_v4i32_v16i16( 286; CHECK-SAME: <4 x i32> [[A0:%.*]], <4 x i32> [[A1:%.*]]) #[[ATTR0]] { 287; CHECK-NEXT: [[X0:%.*]] = bitcast <4 x i32> [[A0]] to <8 x i16> 288; CHECK-NEXT: [[X1:%.*]] = bitcast <4 x i32> [[A1]] to <8 x i16> 289; CHECK-NEXT: [[R:%.*]] = shufflevector <8 x i16> [[X0]], <8 x i16> [[X1]], <16 x i32> <i32 1, i32 0, i32 3, i32 3, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14> 290; CHECK-NEXT: ret <16 x i16> [[R]] 291; 292 %x0 = bitcast <4 x i32> %a0 to <8 x i16> 293 %x1 = bitcast <4 x i32> %a1 to <8 x i16> 294 %r = shufflevector <8 x i16> %x0, <8 x i16> %x1, <16 x i32> <i32 1, i32 0, i32 3, i32 3, i32 5, i32 4, i32 7, i32 6, i32 9, i32 8, i32 11, i32 10, i32 13, i32 12, i32 15, i32 14> 295 ret <16 x i16> %r 296} 297 298; negative - bitcasts (unscalable element counts) 299 300define <4 x i32> @shuffle_bitcast_v32i40_v4i32(<32 x i40> %a0, <32 x i40> %a1) { 301; CHECK-LABEL: define <4 x i32> @shuffle_bitcast_v32i40_v4i32( 302; CHECK-SAME: <32 x i40> [[A0:%.*]], <32 x i40> [[A1:%.*]]) #[[ATTR0]] { 303; CHECK-NEXT: [[X0:%.*]] = bitcast <32 x i40> [[A0]] to <40 x i32> 304; CHECK-NEXT: [[X1:%.*]] = bitcast <32 x i40> [[A1]] to <40 x i32> 305; CHECK-NEXT: [[R:%.*]] = shufflevector <40 x i32> [[X0]], <40 x i32> [[X1]], <4 x i32> <i32 0, i32 42, i32 poison, i32 poison> 306; CHECK-NEXT: ret <4 x i32> [[R]] 307; 308 %x0 = bitcast <32 x i40> %a0 to <40 x i32> 309 %x1 = bitcast <32 x i40> %a1 to <40 x i32> 310 %r = shufflevector <40 x i32> %x0, <40 x i32> %x1, <4 x i32> <i32 0, i32 42, i32 poison, i32 poison> 311 ret <4 x i32> %r 312} 313 314; negative - src type mismatch 315 316define <8 x i32> @concat_sext_v4i8_v4i16_v8i32(<4 x i8> %a0, <4 x i16> %a1) { 317; CHECK-LABEL: define <8 x i32> @concat_sext_v4i8_v4i16_v8i32( 318; CHECK-SAME: <4 x i8> [[A0:%.*]], <4 x i16> [[A1:%.*]]) #[[ATTR0]] { 319; CHECK-NEXT: [[X0:%.*]] = sext <4 x i8> [[A0]] to <4 x i32> 320; CHECK-NEXT: [[X1:%.*]] = sext <4 x i16> [[A1]] to <4 x i32> 321; CHECK-NEXT: [[R:%.*]] = shufflevector <4 x i32> [[X0]], <4 x i32> [[X1]], <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 322; CHECK-NEXT: ret <8 x i32> [[R]] 323; 324 %x0 = sext <4 x i8> %a0 to <4 x i32> 325 %x1 = sext <4 x i16> %a1 to <4 x i32> 326 %r = shufflevector <4 x i32> %x0, <4 x i32> %x1, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> 327 ret <8 x i32> %r 328} 329 330; negative - castop mismatch 331 332define <16 x i32> @concat_sext_zext_v8i16_v16i32(<8 x i16> %a0, <8 x i16> %a1) { 333; CHECK-LABEL: define <16 x i32> @concat_sext_zext_v8i16_v16i32( 334; CHECK-SAME: <8 x i16> [[A0:%.*]], <8 x i16> [[A1:%.*]]) #[[ATTR0]] { 335; CHECK-NEXT: [[X0:%.*]] = sext <8 x i16> [[A0]] to <8 x i32> 336; CHECK-NEXT: [[X1:%.*]] = zext <8 x i16> [[A1]] to <8 x i32> 337; CHECK-NEXT: [[R:%.*]] = shufflevector <8 x i32> [[X0]], <8 x i32> [[X1]], <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> 338; CHECK-NEXT: ret <16 x i32> [[R]] 339; 340 %x0 = sext <8 x i16> %a0 to <8 x i32> 341 %x1 = zext <8 x i16> %a1 to <8 x i32> 342 %r = shufflevector <8 x i32> %x0, <8 x i32> %x1, <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> 343 ret <16 x i32> %r 344} 345