1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc -mtriple=aarch64-unknown-linux-gnu < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD 3; RUN: llc -mtriple=aarch64-unknown-linux-gnu -global-isel -global-isel-abort=2 2>&1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI 4 5; CHECK-GI: warning: Instruction selection used fallback path for freeze_v2i8 6 7%struct.T = type { i32, i32 } 8 9define i32 @freeze_int() { 10; CHECK-LABEL: freeze_int: 11; CHECK: // %bb.0: 12; CHECK-NEXT: mul w0, w8, w8 13; CHECK-NEXT: ret 14 %y1 = freeze i32 undef 15 %t1 = mul i32 %y1, %y1 16 ret i32 %t1 17} 18 19define i5 @freeze_int2() { 20; CHECK-LABEL: freeze_int2: 21; CHECK: // %bb.0: 22; CHECK-NEXT: mul w0, w8, w8 23; CHECK-NEXT: ret 24 %y1 = freeze i5 undef 25 %t1 = mul i5 %y1, %y1 26 ret i5 %t1 27} 28 29define float @freeze_float() { 30; CHECK-LABEL: freeze_float: 31; CHECK: // %bb.0: 32; CHECK-NEXT: fadd s0, s0, s0 33; CHECK-NEXT: ret 34 %y1 = freeze float undef 35 %t1 = fadd float %y1, %y1 36 ret float %t1 37} 38 39define <2 x i8> @freeze_v2i8() { 40; CHECK-LABEL: freeze_v2i8: 41; CHECK: // %bb.0: 42; CHECK-NEXT: add v0.2s, v0.2s, v0.2s 43; CHECK-NEXT: ret 44 %y1 = freeze <2 x i8> undef 45 %t1 = add <2 x i8> %y1, %y1 46 ret <2 x i8> %t1 47} 48 49define <3 x i8> @freeze_v3i8() { 50; CHECK-SD-LABEL: freeze_v3i8: 51; CHECK-SD: // %bb.0: 52; CHECK-SD-NEXT: add v0.4h, v0.4h, v0.4h 53; CHECK-SD-NEXT: umov w0, v0.h[0] 54; CHECK-SD-NEXT: umov w1, v0.h[1] 55; CHECK-SD-NEXT: umov w2, v0.h[2] 56; CHECK-SD-NEXT: ret 57; 58; CHECK-GI-LABEL: freeze_v3i8: 59; CHECK-GI: // %bb.0: 60; CHECK-GI-NEXT: mov b0, v0.b[1] 61; CHECK-GI-NEXT: mov b1, v0.b[2] 62; CHECK-GI-NEXT: fmov w8, s0 63; CHECK-GI-NEXT: mov v0.h[1], w8 64; CHECK-GI-NEXT: fmov w8, s1 65; CHECK-GI-NEXT: mov v0.h[2], w8 66; CHECK-GI-NEXT: add v0.4h, v0.4h, v0.4h 67; CHECK-GI-NEXT: umov w0, v0.h[0] 68; CHECK-GI-NEXT: umov w1, v0.h[1] 69; CHECK-GI-NEXT: umov w2, v0.h[2] 70; CHECK-GI-NEXT: ret 71 %y1 = freeze <3 x i8> undef 72 %t1 = add <3 x i8> %y1, %y1 73 ret <3 x i8> %t1 74} 75 76define <4 x i8> @freeze_v4i8() { 77; CHECK-SD-LABEL: freeze_v4i8: 78; CHECK-SD: // %bb.0: 79; CHECK-SD-NEXT: add v0.4h, v0.4h, v0.4h 80; CHECK-SD-NEXT: ret 81; 82; CHECK-GI-LABEL: freeze_v4i8: 83; CHECK-GI: // %bb.0: 84; CHECK-GI-NEXT: mov b0, v0.b[1] 85; CHECK-GI-NEXT: fmov w8, s0 86; CHECK-GI-NEXT: mov b1, v0.b[2] 87; CHECK-GI-NEXT: mov v0.h[1], w8 88; CHECK-GI-NEXT: fmov w8, s1 89; CHECK-GI-NEXT: mov b2, v0.b[3] 90; CHECK-GI-NEXT: mov v0.h[2], w8 91; CHECK-GI-NEXT: fmov w8, s2 92; CHECK-GI-NEXT: mov v0.h[3], w8 93; CHECK-GI-NEXT: add v0.4h, v0.4h, v0.4h 94; CHECK-GI-NEXT: ret 95 %y1 = freeze <4 x i8> undef 96 %t1 = add <4 x i8> %y1, %y1 97 ret <4 x i8> %t1 98} 99 100define <8 x i8> @freeze_v8i8() { 101; CHECK-LABEL: freeze_v8i8: 102; CHECK: // %bb.0: 103; CHECK-NEXT: add v0.8b, v0.8b, v0.8b 104; CHECK-NEXT: ret 105 %y1 = freeze <8 x i8> undef 106 %t1 = add <8 x i8> %y1, %y1 107 ret <8 x i8> %t1 108} 109 110define <16 x i8> @freeze_v16i8() { 111; CHECK-LABEL: freeze_v16i8: 112; CHECK: // %bb.0: 113; CHECK-NEXT: add v0.16b, v0.16b, v0.16b 114; CHECK-NEXT: ret 115 %y1 = freeze <16 x i8> undef 116 %t1 = add <16 x i8> %y1, %y1 117 ret <16 x i8> %t1 118} 119 120define <32 x i8> @freeze_v32i8() { 121; CHECK-LABEL: freeze_v32i8: 122; CHECK: // %bb.0: 123; CHECK-NEXT: add v0.16b, v0.16b, v0.16b 124; CHECK-NEXT: mov v1.16b, v0.16b 125; CHECK-NEXT: ret 126 %y1 = freeze <32 x i8> undef 127 %t1 = add <32 x i8> %y1, %y1 128 ret <32 x i8> %t1 129} 130 131define <2 x i16> @freeze_v2i16() { 132; CHECK-SD-LABEL: freeze_v2i16: 133; CHECK-SD: // %bb.0: 134; CHECK-SD-NEXT: add v0.2s, v0.2s, v0.2s 135; CHECK-SD-NEXT: ret 136; 137; CHECK-GI-LABEL: freeze_v2i16: 138; CHECK-GI: // %bb.0: 139; CHECK-GI-NEXT: mov h0, v0.h[1] 140; CHECK-GI-NEXT: mov v1.s[0], w8 141; CHECK-GI-NEXT: fmov w8, s0 142; CHECK-GI-NEXT: mov v1.s[1], w8 143; CHECK-GI-NEXT: add v0.2s, v1.2s, v1.2s 144; CHECK-GI-NEXT: ret 145 %y1 = freeze <2 x i16> undef 146 %t1 = add <2 x i16> %y1, %y1 147 ret <2 x i16> %t1 148} 149 150define <3 x i16> @freeze_v3i16() { 151; CHECK-LABEL: freeze_v3i16: 152; CHECK: // %bb.0: 153; CHECK-NEXT: add v0.4h, v0.4h, v0.4h 154; CHECK-NEXT: ret 155 %y1 = freeze <3 x i16> undef 156 %t1 = add <3 x i16> %y1, %y1 157 ret <3 x i16> %t1 158} 159 160define <4 x i16> @freeze_v4i16() { 161; CHECK-LABEL: freeze_v4i16: 162; CHECK: // %bb.0: 163; CHECK-NEXT: add v0.4h, v0.4h, v0.4h 164; CHECK-NEXT: ret 165 %y1 = freeze <4 x i16> undef 166 %t1 = add <4 x i16> %y1, %y1 167 ret <4 x i16> %t1 168} 169 170define <8 x i16> @freeze_v8i16() { 171; CHECK-LABEL: freeze_v8i16: 172; CHECK: // %bb.0: 173; CHECK-NEXT: add v0.8h, v0.8h, v0.8h 174; CHECK-NEXT: ret 175 %y1 = freeze <8 x i16> undef 176 %t1 = add <8 x i16> %y1, %y1 177 ret <8 x i16> %t1 178} 179 180define <16 x i16> @freeze_v16i16() { 181; CHECK-LABEL: freeze_v16i16: 182; CHECK: // %bb.0: 183; CHECK-NEXT: add v0.8h, v0.8h, v0.8h 184; CHECK-NEXT: mov v1.16b, v0.16b 185; CHECK-NEXT: ret 186 %y1 = freeze <16 x i16> undef 187 %t1 = add <16 x i16> %y1, %y1 188 ret <16 x i16> %t1 189} 190 191define <2 x i32> @freeze_v2i32() { 192; CHECK-LABEL: freeze_v2i32: 193; CHECK: // %bb.0: 194; CHECK-NEXT: add v0.2s, v0.2s, v0.2s 195; CHECK-NEXT: ret 196 %y1 = freeze <2 x i32> undef 197 %t1 = add <2 x i32> %y1, %y1 198 ret <2 x i32> %t1 199} 200 201define <3 x i32> @freeze_v3i32() { 202; CHECK-LABEL: freeze_v3i32: 203; CHECK: // %bb.0: 204; CHECK-NEXT: add v0.4s, v0.4s, v0.4s 205; CHECK-NEXT: ret 206 %y1 = freeze <3 x i32> undef 207 %t1 = add <3 x i32> %y1, %y1 208 ret <3 x i32> %t1 209} 210 211define <4 x i32> @freeze_v4i32() { 212; CHECK-LABEL: freeze_v4i32: 213; CHECK: // %bb.0: 214; CHECK-NEXT: add v0.4s, v0.4s, v0.4s 215; CHECK-NEXT: ret 216 %y1 = freeze <4 x i32> undef 217 %t1 = add <4 x i32> %y1, %y1 218 ret <4 x i32> %t1 219} 220 221define <8 x i32> @freeze_v8i32() { 222; CHECK-LABEL: freeze_v8i32: 223; CHECK: // %bb.0: 224; CHECK-NEXT: add v0.4s, v0.4s, v0.4s 225; CHECK-NEXT: mov v1.16b, v0.16b 226; CHECK-NEXT: ret 227 %y1 = freeze <8 x i32> undef 228 %t1 = add <8 x i32> %y1, %y1 229 ret <8 x i32> %t1 230} 231 232define <2 x i64> @freeze_v2i64() { 233; CHECK-LABEL: freeze_v2i64: 234; CHECK: // %bb.0: 235; CHECK-NEXT: add v0.2d, v0.2d, v0.2d 236; CHECK-NEXT: ret 237 %y1 = freeze <2 x i64> undef 238 %t1 = add <2 x i64> %y1, %y1 239 ret <2 x i64> %t1 240} 241 242define <3 x i64> @freeze_v3i64() { 243; CHECK-SD-LABEL: freeze_v3i64: 244; CHECK-SD: // %bb.0: 245; CHECK-SD-NEXT: add v0.2d, v0.2d, v0.2d 246; CHECK-SD-NEXT: fmov d2, d0 247; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8 248; CHECK-SD-NEXT: // kill: def $d1 killed $d1 killed $q1 249; CHECK-SD-NEXT: ret 250; 251; CHECK-GI-LABEL: freeze_v3i64: 252; CHECK-GI: // %bb.0: 253; CHECK-GI-NEXT: add v0.2d, v0.2d, v0.2d 254; CHECK-GI-NEXT: add x8, x8, x8 255; CHECK-GI-NEXT: fmov d2, x8 256; CHECK-GI-NEXT: mov d1, v0.d[1] 257; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 258; CHECK-GI-NEXT: ret 259 %y1 = freeze <3 x i64> undef 260 %t1 = add <3 x i64> %y1, %y1 261 ret <3 x i64> %t1 262} 263 264define <4 x i64> @freeze_v4i64() { 265; CHECK-LABEL: freeze_v4i64: 266; CHECK: // %bb.0: 267; CHECK-NEXT: add v0.2d, v0.2d, v0.2d 268; CHECK-NEXT: mov v1.16b, v0.16b 269; CHECK-NEXT: ret 270 %y1 = freeze <4 x i64> undef 271 %t1 = add <4 x i64> %y1, %y1 272 ret <4 x i64> %t1 273} 274 275define <2 x ptr> @freeze_v2p0() { 276; CHECK-SD-LABEL: freeze_v2p0: 277; CHECK-SD: // %bb.0: 278; CHECK-SD-NEXT: mov w8, #4 // =0x4 279; CHECK-SD-NEXT: dup v0.2d, x8 280; CHECK-SD-NEXT: add v0.2d, v0.2d, v0.2d 281; CHECK-SD-NEXT: ret 282; 283; CHECK-GI-LABEL: freeze_v2p0: 284; CHECK-GI: // %bb.0: 285; CHECK-GI-NEXT: adrp x8, .LCPI21_0 286; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI21_0] 287; CHECK-GI-NEXT: add v0.2d, v0.2d, v0.2d 288; CHECK-GI-NEXT: ret 289 %y1 = freeze <2 x ptr> undef 290 %t1 = getelementptr i32, <2 x ptr> %y1, i32 1 291 ret <2 x ptr> %t1 292} 293 294define <3 x ptr> @freeze_v3p0() { 295; CHECK-SD-LABEL: freeze_v3p0: 296; CHECK-SD: // %bb.0: 297; CHECK-SD-NEXT: mov w8, #4 // =0x4 298; CHECK-SD-NEXT: dup v2.2d, x8 299; CHECK-SD-NEXT: add v0.2d, v0.2d, v2.2d 300; CHECK-SD-NEXT: add d2, d0, d2 301; CHECK-SD-NEXT: ext v1.16b, v0.16b, v0.16b, #8 302; CHECK-SD-NEXT: // kill: def $d0 killed $d0 killed $q0 303; CHECK-SD-NEXT: // kill: def $d1 killed $d1 killed $q1 304; CHECK-SD-NEXT: ret 305; 306; CHECK-GI-LABEL: freeze_v3p0: 307; CHECK-GI: // %bb.0: 308; CHECK-GI-NEXT: adrp x8, .LCPI22_0 309; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI22_0] 310; CHECK-GI-NEXT: add x8, x8, #4 311; CHECK-GI-NEXT: fmov d2, x8 312; CHECK-GI-NEXT: add v0.2d, v0.2d, v0.2d 313; CHECK-GI-NEXT: mov d1, v0.d[1] 314; CHECK-GI-NEXT: ret 315 %y1 = freeze <3 x ptr> undef 316 %t1 = getelementptr i32, <3 x ptr> %y1, i32 1 317 ret <3 x ptr> %t1 318} 319 320define <4 x ptr> @freeze_v4p0() { 321; CHECK-SD-LABEL: freeze_v4p0: 322; CHECK-SD: // %bb.0: 323; CHECK-SD-NEXT: mov w8, #4 // =0x4 324; CHECK-SD-NEXT: dup v0.2d, x8 325; CHECK-SD-NEXT: add v0.2d, v0.2d, v0.2d 326; CHECK-SD-NEXT: mov v1.16b, v0.16b 327; CHECK-SD-NEXT: ret 328; 329; CHECK-GI-LABEL: freeze_v4p0: 330; CHECK-GI: // %bb.0: 331; CHECK-GI-NEXT: adrp x8, .LCPI23_0 332; CHECK-GI-NEXT: ldr q0, [x8, :lo12:.LCPI23_0] 333; CHECK-GI-NEXT: add v0.2d, v0.2d, v0.2d 334; CHECK-GI-NEXT: mov v1.16b, v0.16b 335; CHECK-GI-NEXT: ret 336 %y1 = freeze <4 x ptr> undef 337 %t1 = getelementptr i32, <4 x ptr> %y1, i32 1 338 ret <4 x ptr> %t1 339} 340 341define ptr @freeze_ptr() { 342; CHECK-LABEL: freeze_ptr: 343; CHECK: // %bb.0: 344; CHECK-NEXT: add x0, x8, #4 345; CHECK-NEXT: ret 346 %y1 = freeze ptr undef 347 %t1 = getelementptr i8, ptr %y1, i64 4 348 ret ptr %t1 349} 350 351define i32 @freeze_struct() { 352; CHECK-LABEL: freeze_struct: 353; CHECK: // %bb.0: 354; CHECK-NEXT: add w0, w8, w8 355; CHECK-NEXT: ret 356 %y1 = freeze %struct.T undef 357 %v1 = extractvalue %struct.T %y1, 0 358 %v2 = extractvalue %struct.T %y1, 1 359 %t1 = add i32 %v1, %v2 360 ret i32 %t1 361} 362 363define i32 @freeze_anonstruct() { 364; CHECK-LABEL: freeze_anonstruct: 365; CHECK: // %bb.0: 366; CHECK-NEXT: add w0, w8, w8 367; CHECK-NEXT: ret 368 %y1 = freeze {i32, i32} undef 369 %v1 = extractvalue {i32, i32} %y1, 0 370 %v2 = extractvalue {i32, i32} %y1, 1 371 %t1 = add i32 %v1, %v2 372 ret i32 %t1 373} 374 375define i32 @freeze_anonstruct2() { 376; CHECK-LABEL: freeze_anonstruct2: 377; CHECK: // %bb.0: 378; CHECK-NEXT: add w0, w8, w8, uxth 379; CHECK-NEXT: ret 380 %y1 = freeze {i32, i16} undef 381 %v1 = extractvalue {i32, i16} %y1, 0 382 %v2 = extractvalue {i32, i16} %y1, 1 383 %z2 = zext i16 %v2 to i32 384 %t1 = add i32 %v1, %z2 385 ret i32 %t1 386} 387 388define i64 @freeze_array() { 389; CHECK-LABEL: freeze_array: 390; CHECK: // %bb.0: 391; CHECK-NEXT: add x0, x8, x8 392; CHECK-NEXT: ret 393 %y1 = freeze [2 x i64] undef 394 %v1 = extractvalue [2 x i64] %y1, 0 395 %v2 = extractvalue [2 x i64] %y1, 1 396 %t1 = add i64 %v1, %v2 397 ret i64 %t1 398} 399