1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py 2; RUN: llc < %s -mtriple=aarch64-unknown-unknown | FileCheck %s 3 4declare void @use(i32 %arg) 5declare void @vec_use(<4 x i32> %arg) 6 7; (x+c1)+c2 8 9define i32 @add_const_add_const(i32 %arg) { 10; CHECK-LABEL: add_const_add_const: 11; CHECK: // %bb.0: 12; CHECK-NEXT: add w0, w0, #10 13; CHECK-NEXT: ret 14 %t0 = add i32 %arg, 8 15 %t1 = add i32 %t0, 2 16 ret i32 %t1 17} 18 19define i32 @add_const_add_const_extrause(i32 %arg) { 20; CHECK-LABEL: add_const_add_const_extrause: 21; CHECK: // %bb.0: 22; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 23; CHECK-NEXT: .cfi_def_cfa_offset 16 24; CHECK-NEXT: .cfi_offset w19, -8 25; CHECK-NEXT: .cfi_offset w30, -16 26; CHECK-NEXT: mov w19, w0 27; CHECK-NEXT: add w0, w0, #8 28; CHECK-NEXT: bl use 29; CHECK-NEXT: add w0, w19, #10 30; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 31; CHECK-NEXT: ret 32 %t0 = add i32 %arg, 8 33 call void @use(i32 %t0) 34 %t1 = add i32 %t0, 2 35 ret i32 %t1 36} 37 38define <4 x i32> @vec_add_const_add_const(<4 x i32> %arg) { 39; CHECK-LABEL: vec_add_const_add_const: 40; CHECK: // %bb.0: 41; CHECK-NEXT: movi v1.4s, #10 42; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 43; CHECK-NEXT: ret 44 %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 45 %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 46 ret <4 x i32> %t1 47} 48 49define <4 x i32> @vec_add_const_add_const_extrause(<4 x i32> %arg) { 50; CHECK-LABEL: vec_add_const_add_const_extrause: 51; CHECK: // %bb.0: 52; CHECK-NEXT: sub sp, sp, #32 53; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 54; CHECK-NEXT: .cfi_def_cfa_offset 32 55; CHECK-NEXT: .cfi_offset w30, -16 56; CHECK-NEXT: movi v1.4s, #8 57; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 58; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 59; CHECK-NEXT: bl vec_use 60; CHECK-NEXT: movi v0.4s, #10 61; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 62; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 63; CHECK-NEXT: add v0.4s, v1.4s, v0.4s 64; CHECK-NEXT: add sp, sp, #32 65; CHECK-NEXT: ret 66 %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 67 call void @vec_use(<4 x i32> %t0) 68 %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 69 ret <4 x i32> %t1 70} 71 72define <4 x i32> @vec_add_const_add_const_nonsplat(<4 x i32> %arg) { 73; CHECK-LABEL: vec_add_const_add_const_nonsplat: 74; CHECK: // %bb.0: 75; CHECK-NEXT: adrp x8, .LCPI4_0 76; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI4_0] 77; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 78; CHECK-NEXT: ret 79 %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8> 80 %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2> 81 ret <4 x i32> %t1 82} 83 84; (x+c1)-c2 85 86define i32 @add_const_sub_const(i32 %arg) { 87; CHECK-LABEL: add_const_sub_const: 88; CHECK: // %bb.0: 89; CHECK-NEXT: add w0, w0, #6 90; CHECK-NEXT: ret 91 %t0 = add i32 %arg, 8 92 %t1 = sub i32 %t0, 2 93 ret i32 %t1 94} 95 96define i32 @add_const_sub_const_extrause(i32 %arg) { 97; CHECK-LABEL: add_const_sub_const_extrause: 98; CHECK: // %bb.0: 99; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 100; CHECK-NEXT: .cfi_def_cfa_offset 16 101; CHECK-NEXT: .cfi_offset w19, -8 102; CHECK-NEXT: .cfi_offset w30, -16 103; CHECK-NEXT: mov w19, w0 104; CHECK-NEXT: add w0, w0, #8 105; CHECK-NEXT: bl use 106; CHECK-NEXT: add w0, w19, #6 107; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 108; CHECK-NEXT: ret 109 %t0 = add i32 %arg, 8 110 call void @use(i32 %t0) 111 %t1 = sub i32 %t0, 2 112 ret i32 %t1 113} 114 115define <4 x i32> @vec_add_const_sub_const(<4 x i32> %arg) { 116; CHECK-LABEL: vec_add_const_sub_const: 117; CHECK: // %bb.0: 118; CHECK-NEXT: movi v1.4s, #6 119; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 120; CHECK-NEXT: ret 121 %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 122 %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 123 ret <4 x i32> %t1 124} 125 126define <4 x i32> @vec_add_const_sub_const_extrause(<4 x i32> %arg) { 127; CHECK-LABEL: vec_add_const_sub_const_extrause: 128; CHECK: // %bb.0: 129; CHECK-NEXT: sub sp, sp, #32 130; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 131; CHECK-NEXT: .cfi_def_cfa_offset 32 132; CHECK-NEXT: .cfi_offset w30, -16 133; CHECK-NEXT: movi v1.4s, #8 134; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 135; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 136; CHECK-NEXT: bl vec_use 137; CHECK-NEXT: movi v0.4s, #6 138; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 139; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 140; CHECK-NEXT: add v0.4s, v1.4s, v0.4s 141; CHECK-NEXT: add sp, sp, #32 142; CHECK-NEXT: ret 143 %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 144 call void @vec_use(<4 x i32> %t0) 145 %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 146 ret <4 x i32> %t1 147} 148 149define <4 x i32> @vec_add_const_sub_const_nonsplat(<4 x i32> %arg) { 150; CHECK-LABEL: vec_add_const_sub_const_nonsplat: 151; CHECK: // %bb.0: 152; CHECK-NEXT: adrp x8, .LCPI9_0 153; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI9_0] 154; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 155; CHECK-NEXT: ret 156 %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8> 157 %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2> 158 ret <4 x i32> %t1 159} 160 161; c2-(x+c1) 162 163define i32 @add_const_const_sub(i32 %arg) { 164; CHECK-LABEL: add_const_const_sub: 165; CHECK: // %bb.0: 166; CHECK-NEXT: mov w8, #-6 // =0xfffffffa 167; CHECK-NEXT: sub w0, w8, w0 168; CHECK-NEXT: ret 169 %t0 = add i32 %arg, 8 170 %t1 = sub i32 2, %t0 171 ret i32 %t1 172} 173 174define i32 @add_const_const_sub_extrause(i32 %arg) { 175; CHECK-LABEL: add_const_const_sub_extrause: 176; CHECK: // %bb.0: 177; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 178; CHECK-NEXT: .cfi_def_cfa_offset 16 179; CHECK-NEXT: .cfi_offset w19, -8 180; CHECK-NEXT: .cfi_offset w30, -16 181; CHECK-NEXT: mov w19, w0 182; CHECK-NEXT: add w0, w0, #8 183; CHECK-NEXT: bl use 184; CHECK-NEXT: mov w8, #-6 // =0xfffffffa 185; CHECK-NEXT: sub w0, w8, w19 186; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 187; CHECK-NEXT: ret 188 %t0 = add i32 %arg, 8 189 call void @use(i32 %t0) 190 %t1 = sub i32 2, %t0 191 ret i32 %t1 192} 193 194define <4 x i32> @vec_add_const_const_sub(<4 x i32> %arg) { 195; CHECK-LABEL: vec_add_const_const_sub: 196; CHECK: // %bb.0: 197; CHECK-NEXT: mvni v1.4s, #5 198; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 199; CHECK-NEXT: ret 200 %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 201 %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0 202 ret <4 x i32> %t1 203} 204 205define <4 x i32> @vec_add_const_const_sub_extrause(<4 x i32> %arg) { 206; CHECK-LABEL: vec_add_const_const_sub_extrause: 207; CHECK: // %bb.0: 208; CHECK-NEXT: sub sp, sp, #32 209; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 210; CHECK-NEXT: .cfi_def_cfa_offset 32 211; CHECK-NEXT: .cfi_offset w30, -16 212; CHECK-NEXT: movi v1.4s, #8 213; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 214; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 215; CHECK-NEXT: bl vec_use 216; CHECK-NEXT: mvni v0.4s, #5 217; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 218; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 219; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 220; CHECK-NEXT: add sp, sp, #32 221; CHECK-NEXT: ret 222 %t0 = add <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 223 call void @vec_use(<4 x i32> %t0) 224 %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0 225 ret <4 x i32> %t1 226} 227 228define <4 x i32> @vec_add_const_const_sub_nonsplat(<4 x i32> %arg) { 229; CHECK-LABEL: vec_add_const_const_sub_nonsplat: 230; CHECK: // %bb.0: 231; CHECK-NEXT: adrp x8, .LCPI14_0 232; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI14_0] 233; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 234; CHECK-NEXT: ret 235 %t0 = add <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8> 236 %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0 237 ret <4 x i32> %t1 238} 239 240; (x-c1)+c2 241 242define i32 @sub_const_add_const(i32 %arg) { 243; CHECK-LABEL: sub_const_add_const: 244; CHECK: // %bb.0: 245; CHECK-NEXT: sub w0, w0, #6 246; CHECK-NEXT: ret 247 %t0 = sub i32 %arg, 8 248 %t1 = add i32 %t0, 2 249 ret i32 %t1 250} 251 252define i32 @sub_const_add_const_extrause(i32 %arg) { 253; CHECK-LABEL: sub_const_add_const_extrause: 254; CHECK: // %bb.0: 255; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 256; CHECK-NEXT: .cfi_def_cfa_offset 16 257; CHECK-NEXT: .cfi_offset w19, -8 258; CHECK-NEXT: .cfi_offset w30, -16 259; CHECK-NEXT: mov w19, w0 260; CHECK-NEXT: sub w0, w0, #8 261; CHECK-NEXT: bl use 262; CHECK-NEXT: sub w0, w19, #6 263; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 264; CHECK-NEXT: ret 265 %t0 = sub i32 %arg, 8 266 call void @use(i32 %t0) 267 %t1 = add i32 %t0, 2 268 ret i32 %t1 269} 270 271define <4 x i32> @vec_sub_const_add_const(<4 x i32> %arg) { 272; CHECK-LABEL: vec_sub_const_add_const: 273; CHECK: // %bb.0: 274; CHECK-NEXT: mvni v1.4s, #5 275; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 276; CHECK-NEXT: ret 277 %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 278 %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 279 ret <4 x i32> %t1 280} 281 282define <4 x i32> @vec_sub_const_add_const_extrause(<4 x i32> %arg) { 283; CHECK-LABEL: vec_sub_const_add_const_extrause: 284; CHECK: // %bb.0: 285; CHECK-NEXT: sub sp, sp, #32 286; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 287; CHECK-NEXT: .cfi_def_cfa_offset 32 288; CHECK-NEXT: .cfi_offset w30, -16 289; CHECK-NEXT: movi v1.4s, #8 290; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 291; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 292; CHECK-NEXT: bl vec_use 293; CHECK-NEXT: mvni v0.4s, #5 294; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 295; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 296; CHECK-NEXT: add v0.4s, v1.4s, v0.4s 297; CHECK-NEXT: add sp, sp, #32 298; CHECK-NEXT: ret 299 %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 300 call void @vec_use(<4 x i32> %t0) 301 %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 302 ret <4 x i32> %t1 303} 304 305define <4 x i32> @vec_sub_const_add_const_nonsplat(<4 x i32> %arg) { 306; CHECK-LABEL: vec_sub_const_add_const_nonsplat: 307; CHECK: // %bb.0: 308; CHECK-NEXT: adrp x8, .LCPI19_0 309; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI19_0] 310; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 311; CHECK-NEXT: ret 312 %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8> 313 %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2> 314 ret <4 x i32> %t1 315} 316 317; (x-c1)-c2 318 319define i32 @sub_const_sub_const(i32 %arg) { 320; CHECK-LABEL: sub_const_sub_const: 321; CHECK: // %bb.0: 322; CHECK-NEXT: sub w0, w0, #10 323; CHECK-NEXT: ret 324 %t0 = sub i32 %arg, 8 325 %t1 = sub i32 %t0, 2 326 ret i32 %t1 327} 328 329define i32 @sub_const_sub_const_extrause(i32 %arg) { 330; CHECK-LABEL: sub_const_sub_const_extrause: 331; CHECK: // %bb.0: 332; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 333; CHECK-NEXT: .cfi_def_cfa_offset 16 334; CHECK-NEXT: .cfi_offset w19, -8 335; CHECK-NEXT: .cfi_offset w30, -16 336; CHECK-NEXT: mov w19, w0 337; CHECK-NEXT: sub w0, w0, #8 338; CHECK-NEXT: bl use 339; CHECK-NEXT: sub w0, w19, #10 340; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 341; CHECK-NEXT: ret 342 %t0 = sub i32 %arg, 8 343 call void @use(i32 %t0) 344 %t1 = sub i32 %t0, 2 345 ret i32 %t1 346} 347 348define <4 x i32> @vec_sub_const_sub_const(<4 x i32> %arg) { 349; CHECK-LABEL: vec_sub_const_sub_const: 350; CHECK: // %bb.0: 351; CHECK-NEXT: movi v1.4s, #10 352; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 353; CHECK-NEXT: ret 354 %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 355 %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 356 ret <4 x i32> %t1 357} 358 359define <4 x i32> @vec_sub_const_sub_const_extrause(<4 x i32> %arg) { 360; CHECK-LABEL: vec_sub_const_sub_const_extrause: 361; CHECK: // %bb.0: 362; CHECK-NEXT: sub sp, sp, #32 363; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 364; CHECK-NEXT: .cfi_def_cfa_offset 32 365; CHECK-NEXT: .cfi_offset w30, -16 366; CHECK-NEXT: movi v1.4s, #8 367; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 368; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 369; CHECK-NEXT: bl vec_use 370; CHECK-NEXT: movi v0.4s, #10 371; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 372; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 373; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 374; CHECK-NEXT: add sp, sp, #32 375; CHECK-NEXT: ret 376 %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 377 call void @vec_use(<4 x i32> %t0) 378 %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 379 ret <4 x i32> %t1 380} 381 382define <4 x i32> @vec_sub_const_sub_const_nonsplat(<4 x i32> %arg) { 383; CHECK-LABEL: vec_sub_const_sub_const_nonsplat: 384; CHECK: // %bb.0: 385; CHECK-NEXT: adrp x8, .LCPI24_0 386; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI24_0] 387; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 388; CHECK-NEXT: ret 389 %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8> 390 %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2> 391 ret <4 x i32> %t1 392} 393 394; c2-(x-c1) 395 396define i32 @sub_const_const_sub(i32 %arg) { 397; CHECK-LABEL: sub_const_const_sub: 398; CHECK: // %bb.0: 399; CHECK-NEXT: mov w8, #10 // =0xa 400; CHECK-NEXT: sub w0, w8, w0 401; CHECK-NEXT: ret 402 %t0 = sub i32 %arg, 8 403 %t1 = sub i32 2, %t0 404 ret i32 %t1 405} 406 407define i32 @sub_const_const_sub_extrause(i32 %arg) { 408; CHECK-LABEL: sub_const_const_sub_extrause: 409; CHECK: // %bb.0: 410; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 411; CHECK-NEXT: .cfi_def_cfa_offset 16 412; CHECK-NEXT: .cfi_offset w19, -8 413; CHECK-NEXT: .cfi_offset w30, -16 414; CHECK-NEXT: mov w19, w0 415; CHECK-NEXT: sub w0, w0, #8 416; CHECK-NEXT: bl use 417; CHECK-NEXT: mov w8, #10 // =0xa 418; CHECK-NEXT: sub w0, w8, w19 419; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 420; CHECK-NEXT: ret 421 %t0 = sub i32 %arg, 8 422 call void @use(i32 %t0) 423 %t1 = sub i32 2, %t0 424 ret i32 %t1 425} 426 427define <4 x i32> @vec_sub_const_const_sub(<4 x i32> %arg) { 428; CHECK-LABEL: vec_sub_const_const_sub: 429; CHECK: // %bb.0: 430; CHECK-NEXT: movi v1.4s, #10 431; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 432; CHECK-NEXT: ret 433 %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 434 %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0 435 ret <4 x i32> %t1 436} 437 438define <4 x i32> @vec_sub_const_const_sub_extrause(<4 x i32> %arg) { 439; CHECK-LABEL: vec_sub_const_const_sub_extrause: 440; CHECK: // %bb.0: 441; CHECK-NEXT: sub sp, sp, #32 442; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 443; CHECK-NEXT: .cfi_def_cfa_offset 32 444; CHECK-NEXT: .cfi_offset w30, -16 445; CHECK-NEXT: movi v1.4s, #8 446; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 447; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 448; CHECK-NEXT: bl vec_use 449; CHECK-NEXT: movi v0.4s, #2 450; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 451; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 452; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 453; CHECK-NEXT: add sp, sp, #32 454; CHECK-NEXT: ret 455 %t0 = sub <4 x i32> %arg, <i32 8, i32 8, i32 8, i32 8> 456 call void @vec_use(<4 x i32> %t0) 457 %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0 458 ret <4 x i32> %t1 459} 460 461define <4 x i32> @vec_sub_const_const_sub_nonsplat(<4 x i32> %arg) { 462; CHECK-LABEL: vec_sub_const_const_sub_nonsplat: 463; CHECK: // %bb.0: 464; CHECK-NEXT: adrp x8, .LCPI29_0 465; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI29_0] 466; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 467; CHECK-NEXT: ret 468 %t0 = sub <4 x i32> %arg, <i32 21, i32 undef, i32 8, i32 8> 469 %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0 470 ret <4 x i32> %t1 471} 472 473; (c1-x)+c2 474 475define i32 @const_sub_add_const(i32 %arg) { 476; CHECK-LABEL: const_sub_add_const: 477; CHECK: // %bb.0: 478; CHECK-NEXT: mov w8, #10 // =0xa 479; CHECK-NEXT: sub w0, w8, w0 480; CHECK-NEXT: ret 481 %t0 = sub i32 8, %arg 482 %t1 = add i32 %t0, 2 483 ret i32 %t1 484} 485 486define i32 @const_sub_add_const_extrause(i32 %arg) { 487; CHECK-LABEL: const_sub_add_const_extrause: 488; CHECK: // %bb.0: 489; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 490; CHECK-NEXT: .cfi_def_cfa_offset 16 491; CHECK-NEXT: .cfi_offset w19, -8 492; CHECK-NEXT: .cfi_offset w30, -16 493; CHECK-NEXT: mov w8, #8 // =0x8 494; CHECK-NEXT: mov w19, w0 495; CHECK-NEXT: sub w0, w8, w0 496; CHECK-NEXT: bl use 497; CHECK-NEXT: mov w8, #10 // =0xa 498; CHECK-NEXT: sub w0, w8, w19 499; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 500; CHECK-NEXT: ret 501 %t0 = sub i32 8, %arg 502 call void @use(i32 %t0) 503 %t1 = add i32 %t0, 2 504 ret i32 %t1 505} 506 507define <4 x i32> @vec_const_sub_add_const(<4 x i32> %arg) { 508; CHECK-LABEL: vec_const_sub_add_const: 509; CHECK: // %bb.0: 510; CHECK-NEXT: movi v1.4s, #10 511; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 512; CHECK-NEXT: ret 513 %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg 514 %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 515 ret <4 x i32> %t1 516} 517 518define <4 x i32> @vec_const_sub_add_const_extrause(<4 x i32> %arg) { 519; CHECK-LABEL: vec_const_sub_add_const_extrause: 520; CHECK: // %bb.0: 521; CHECK-NEXT: sub sp, sp, #32 522; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 523; CHECK-NEXT: .cfi_def_cfa_offset 32 524; CHECK-NEXT: .cfi_offset w30, -16 525; CHECK-NEXT: movi v1.4s, #8 526; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 527; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 528; CHECK-NEXT: bl vec_use 529; CHECK-NEXT: movi v0.4s, #10 530; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 531; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 532; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 533; CHECK-NEXT: add sp, sp, #32 534; CHECK-NEXT: ret 535 %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg 536 call void @vec_use(<4 x i32> %t0) 537 %t1 = add <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 538 ret <4 x i32> %t1 539} 540 541define <4 x i32> @vec_const_sub_add_const_nonsplat(<4 x i32> %arg) { 542; CHECK-LABEL: vec_const_sub_add_const_nonsplat: 543; CHECK: // %bb.0: 544; CHECK-NEXT: adrp x8, .LCPI34_0 545; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI34_0] 546; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 547; CHECK-NEXT: ret 548 %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg 549 %t1 = add <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2> 550 ret <4 x i32> %t1 551} 552 553; (c1-x)-c2 554 555define i32 @const_sub_sub_const(i32 %arg) { 556; CHECK-LABEL: const_sub_sub_const: 557; CHECK: // %bb.0: 558; CHECK-NEXT: mov w8, #6 // =0x6 559; CHECK-NEXT: sub w0, w8, w0 560; CHECK-NEXT: ret 561 %t0 = sub i32 8, %arg 562 %t1 = sub i32 %t0, 2 563 ret i32 %t1 564} 565 566define i32 @const_sub_sub_const_extrause(i32 %arg) { 567; CHECK-LABEL: const_sub_sub_const_extrause: 568; CHECK: // %bb.0: 569; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 570; CHECK-NEXT: .cfi_def_cfa_offset 16 571; CHECK-NEXT: .cfi_offset w19, -8 572; CHECK-NEXT: .cfi_offset w30, -16 573; CHECK-NEXT: mov w8, #8 // =0x8 574; CHECK-NEXT: mov w19, w0 575; CHECK-NEXT: sub w0, w8, w0 576; CHECK-NEXT: bl use 577; CHECK-NEXT: mov w8, #6 // =0x6 578; CHECK-NEXT: sub w0, w8, w19 579; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 580; CHECK-NEXT: ret 581 %t0 = sub i32 8, %arg 582 call void @use(i32 %t0) 583 %t1 = sub i32 %t0, 2 584 ret i32 %t1 585} 586 587define <4 x i32> @vec_const_sub_sub_const(<4 x i32> %arg) { 588; CHECK-LABEL: vec_const_sub_sub_const: 589; CHECK: // %bb.0: 590; CHECK-NEXT: movi v1.4s, #6 591; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 592; CHECK-NEXT: ret 593 %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg 594 %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 595 ret <4 x i32> %t1 596} 597 598define <4 x i32> @vec_const_sub_sub_const_extrause(<4 x i32> %arg) { 599; CHECK-LABEL: vec_const_sub_sub_const_extrause: 600; CHECK: // %bb.0: 601; CHECK-NEXT: sub sp, sp, #32 602; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 603; CHECK-NEXT: .cfi_def_cfa_offset 32 604; CHECK-NEXT: .cfi_offset w30, -16 605; CHECK-NEXT: movi v1.4s, #8 606; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 607; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 608; CHECK-NEXT: bl vec_use 609; CHECK-NEXT: movi v0.4s, #6 610; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 611; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 612; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 613; CHECK-NEXT: add sp, sp, #32 614; CHECK-NEXT: ret 615 %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg 616 call void @vec_use(<4 x i32> %t0) 617 %t1 = sub <4 x i32> %t0, <i32 2, i32 2, i32 2, i32 2> 618 ret <4 x i32> %t1 619} 620 621define <4 x i32> @vec_const_sub_sub_const_nonsplat(<4 x i32> %arg) { 622; CHECK-LABEL: vec_const_sub_sub_const_nonsplat: 623; CHECK: // %bb.0: 624; CHECK-NEXT: adrp x8, .LCPI39_0 625; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI39_0] 626; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 627; CHECK-NEXT: ret 628 %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg 629 %t1 = sub <4 x i32> %t0, <i32 2, i32 3, i32 undef, i32 2> 630 ret <4 x i32> %t1 631} 632 633; c2-(c1-x) 634 635define i32 @const_sub_const_sub(i32 %arg) { 636; CHECK-LABEL: const_sub_const_sub: 637; CHECK: // %bb.0: 638; CHECK-NEXT: sub w0, w0, #6 639; CHECK-NEXT: ret 640 %t0 = sub i32 8, %arg 641 %t1 = sub i32 2, %t0 642 ret i32 %t1 643} 644 645define i32 @const_sub_const_sub_extrause(i32 %arg) { 646; CHECK-LABEL: const_sub_const_sub_extrause: 647; CHECK: // %bb.0: 648; CHECK-NEXT: stp x30, x19, [sp, #-16]! // 16-byte Folded Spill 649; CHECK-NEXT: .cfi_def_cfa_offset 16 650; CHECK-NEXT: .cfi_offset w19, -8 651; CHECK-NEXT: .cfi_offset w30, -16 652; CHECK-NEXT: mov w8, #8 // =0x8 653; CHECK-NEXT: sub w19, w8, w0 654; CHECK-NEXT: mov w0, w19 655; CHECK-NEXT: bl use 656; CHECK-NEXT: mov w8, #2 // =0x2 657; CHECK-NEXT: sub w0, w8, w19 658; CHECK-NEXT: ldp x30, x19, [sp], #16 // 16-byte Folded Reload 659; CHECK-NEXT: ret 660 %t0 = sub i32 8, %arg 661 call void @use(i32 %t0) 662 %t1 = sub i32 2, %t0 663 ret i32 %t1 664} 665 666define <4 x i32> @vec_const_sub_const_sub(<4 x i32> %arg) { 667; CHECK-LABEL: vec_const_sub_const_sub: 668; CHECK: // %bb.0: 669; CHECK-NEXT: mvni v1.4s, #5 670; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 671; CHECK-NEXT: ret 672 %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg 673 %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0 674 ret <4 x i32> %t1 675} 676 677define <4 x i32> @vec_const_sub_const_sub_extrause(<4 x i32> %arg) { 678; CHECK-LABEL: vec_const_sub_const_sub_extrause: 679; CHECK: // %bb.0: 680; CHECK-NEXT: sub sp, sp, #32 681; CHECK-NEXT: str x30, [sp, #16] // 8-byte Folded Spill 682; CHECK-NEXT: .cfi_def_cfa_offset 32 683; CHECK-NEXT: .cfi_offset w30, -16 684; CHECK-NEXT: movi v1.4s, #8 685; CHECK-NEXT: sub v0.4s, v1.4s, v0.4s 686; CHECK-NEXT: str q0, [sp] // 16-byte Folded Spill 687; CHECK-NEXT: bl vec_use 688; CHECK-NEXT: movi v0.4s, #2 689; CHECK-NEXT: ldr q1, [sp] // 16-byte Folded Reload 690; CHECK-NEXT: ldr x30, [sp, #16] // 8-byte Folded Reload 691; CHECK-NEXT: sub v0.4s, v0.4s, v1.4s 692; CHECK-NEXT: add sp, sp, #32 693; CHECK-NEXT: ret 694 %t0 = sub <4 x i32> <i32 8, i32 8, i32 8, i32 8>, %arg 695 call void @vec_use(<4 x i32> %t0) 696 %t1 = sub <4 x i32> <i32 2, i32 2, i32 2, i32 2>, %t0 697 ret <4 x i32> %t1 698} 699 700define <4 x i32> @vec_const_sub_const_sub_nonsplat(<4 x i32> %arg) { 701; CHECK-LABEL: vec_const_sub_const_sub_nonsplat: 702; CHECK: // %bb.0: 703; CHECK-NEXT: adrp x8, .LCPI44_0 704; CHECK-NEXT: ldr q1, [x8, :lo12:.LCPI44_0] 705; CHECK-NEXT: add v0.4s, v0.4s, v1.4s 706; CHECK-NEXT: ret 707 %t0 = sub <4 x i32> <i32 21, i32 undef, i32 8, i32 8>, %arg 708 %t1 = sub <4 x i32> <i32 2, i32 3, i32 undef, i32 2>, %t0 709 ret <4 x i32> %t1 710} 711