1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4 2; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD 3; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI 4 5; ===== Legal Scalars ===== 6 7define i8 @abs_i8(i8 %a){ 8; CHECK-SD-LABEL: abs_i8: 9; CHECK-SD: // %bb.0: // %entry 10; CHECK-SD-NEXT: sxtb w8, w0 11; CHECK-SD-NEXT: cmp w8, #0 12; CHECK-SD-NEXT: cneg w0, w8, mi 13; CHECK-SD-NEXT: ret 14; 15; CHECK-GI-LABEL: abs_i8: 16; CHECK-GI: // %bb.0: // %entry 17; CHECK-GI-NEXT: sxtb w8, w0 18; CHECK-GI-NEXT: cmp w8, #0 19; CHECK-GI-NEXT: cneg w0, w0, le 20; CHECK-GI-NEXT: ret 21entry: 22 %res = call i8 @llvm.abs.i8(i8 %a, i1 0) 23 ret i8 %res 24} 25declare i8 @llvm.abs.i8(i8, i1) 26 27define i16 @abs_i16(i16 %a){ 28; CHECK-SD-LABEL: abs_i16: 29; CHECK-SD: // %bb.0: // %entry 30; CHECK-SD-NEXT: sxth w8, w0 31; CHECK-SD-NEXT: cmp w8, #0 32; CHECK-SD-NEXT: cneg w0, w8, mi 33; CHECK-SD-NEXT: ret 34; 35; CHECK-GI-LABEL: abs_i16: 36; CHECK-GI: // %bb.0: // %entry 37; CHECK-GI-NEXT: sxth w8, w0 38; CHECK-GI-NEXT: cmp w8, #0 39; CHECK-GI-NEXT: cneg w0, w0, le 40; CHECK-GI-NEXT: ret 41entry: 42 %res = call i16 @llvm.abs.i16(i16 %a, i1 0) 43 ret i16 %res 44} 45declare i16 @llvm.abs.i16(i16, i1) 46 47define i32 @abs_i32(i32 %a){ 48; CHECK-SD-LABEL: abs_i32: 49; CHECK-SD: // %bb.0: // %entry 50; CHECK-SD-NEXT: cmp w0, #0 51; CHECK-SD-NEXT: cneg w0, w0, mi 52; CHECK-SD-NEXT: ret 53; 54; CHECK-GI-LABEL: abs_i32: 55; CHECK-GI: // %bb.0: // %entry 56; CHECK-GI-NEXT: cmp w0, #0 57; CHECK-GI-NEXT: cneg w0, w0, le 58; CHECK-GI-NEXT: ret 59entry: 60 %res = call i32 @llvm.abs.i32(i32 %a, i1 0) 61 ret i32 %res 62} 63declare i32 @llvm.abs.i32(i32, i1) 64 65define i64 @abs_i64(i64 %a){ 66; CHECK-SD-LABEL: abs_i64: 67; CHECK-SD: // %bb.0: // %entry 68; CHECK-SD-NEXT: cmp x0, #0 69; CHECK-SD-NEXT: cneg x0, x0, mi 70; CHECK-SD-NEXT: ret 71; 72; CHECK-GI-LABEL: abs_i64: 73; CHECK-GI: // %bb.0: // %entry 74; CHECK-GI-NEXT: cmp x0, #0 75; CHECK-GI-NEXT: cneg x0, x0, le 76; CHECK-GI-NEXT: ret 77entry: 78 %res = call i64 @llvm.abs.i64(i64 %a, i1 0) 79 ret i64 %res 80} 81declare i64 @llvm.abs.i64(i64, i1) 82 83define i128 @abs_i128(i128 %a){ 84; CHECK-SD-LABEL: abs_i128: 85; CHECK-SD: // %bb.0: // %entry 86; CHECK-SD-NEXT: asr x8, x1, #63 87; CHECK-SD-NEXT: eor x9, x0, x8 88; CHECK-SD-NEXT: eor x10, x1, x8 89; CHECK-SD-NEXT: subs x0, x9, x8 90; CHECK-SD-NEXT: sbc x1, x10, x8 91; CHECK-SD-NEXT: ret 92; 93; CHECK-GI-LABEL: abs_i128: 94; CHECK-GI: // %bb.0: // %entry 95; CHECK-GI-NEXT: asr x8, x1, #63 96; CHECK-GI-NEXT: adds x9, x0, x8 97; CHECK-GI-NEXT: adc x10, x1, x8 98; CHECK-GI-NEXT: eor x0, x9, x8 99; CHECK-GI-NEXT: eor x1, x10, x8 100; CHECK-GI-NEXT: ret 101entry: 102 %res = call i128 @llvm.abs.i128(i128 %a, i1 0) 103 ret i128 %res 104} 105declare i128 @llvm.abs.i128(i128, i1) 106 107; ===== Legal Vector Types ===== 108 109define <8 x i8> @abs_v8i8(<8 x i8> %a){ 110; CHECK-LABEL: abs_v8i8: 111; CHECK: // %bb.0: // %entry 112; CHECK-NEXT: abs v0.8b, v0.8b 113; CHECK-NEXT: ret 114entry: 115 %res = call <8 x i8> @llvm.abs.v8i8(<8 x i8> %a, i1 0) 116 ret <8 x i8> %res 117} 118declare <8 x i8> @llvm.abs.v8i8(<8 x i8>, i1) 119 120define <16 x i8> @abs_v16i8(<16 x i8> %a){ 121; CHECK-LABEL: abs_v16i8: 122; CHECK: // %bb.0: // %entry 123; CHECK-NEXT: abs v0.16b, v0.16b 124; CHECK-NEXT: ret 125entry: 126 %res = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %a, i1 0) 127 ret <16 x i8> %res 128} 129declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1) 130 131define <4 x i16> @abs_v4i16(<4 x i16> %a){ 132; CHECK-LABEL: abs_v4i16: 133; CHECK: // %bb.0: // %entry 134; CHECK-NEXT: abs v0.4h, v0.4h 135; CHECK-NEXT: ret 136entry: 137 %res = call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 0) 138 ret <4 x i16> %res 139} 140declare <4 x i16> @llvm.abs.v4i16(<4 x i16>, i1) 141 142define <8 x i16> @abs_v8i16(<8 x i16> %a){ 143; CHECK-LABEL: abs_v8i16: 144; CHECK: // %bb.0: // %entry 145; CHECK-NEXT: abs v0.8h, v0.8h 146; CHECK-NEXT: ret 147entry: 148 %res = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %a, i1 0) 149 ret <8 x i16> %res 150} 151declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1) 152 153define <2 x i32> @abs_v2i32(<2 x i32> %a){ 154; CHECK-LABEL: abs_v2i32: 155; CHECK: // %bb.0: // %entry 156; CHECK-NEXT: abs v0.2s, v0.2s 157; CHECK-NEXT: ret 158entry: 159 %res = call <2 x i32> @llvm.abs.v2i32(<2 x i32> %a, i1 0) 160 ret <2 x i32> %res 161} 162declare <2 x i32> @llvm.abs.v2i32(<2 x i32>, i1) 163 164define <4 x i32> @abs_v4i32(<4 x i32> %a){ 165; CHECK-LABEL: abs_v4i32: 166; CHECK: // %bb.0: // %entry 167; CHECK-NEXT: abs v0.4s, v0.4s 168; CHECK-NEXT: ret 169entry: 170 %res = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a, i1 0) 171 ret <4 x i32> %res 172} 173declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1) 174 175define <2 x i64> @abs_v2i64(<2 x i64> %a){ 176; CHECK-LABEL: abs_v2i64: 177; CHECK: // %bb.0: // %entry 178; CHECK-NEXT: abs v0.2d, v0.2d 179; CHECK-NEXT: ret 180entry: 181 %res = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %a, i1 0) 182 ret <2 x i64> %res 183} 184declare <2 x i64> @llvm.abs.v2i64(<2 x i64>, i1) 185 186; ===== Smaller/Larger Width Vectors with Legal Element Sizes ===== 187 188define <4 x i8> @abs_v4i8(<4 x i8> %a){ 189; CHECK-LABEL: abs_v4i8: 190; CHECK: // %bb.0: // %entry 191; CHECK-NEXT: shl v0.4h, v0.4h, #8 192; CHECK-NEXT: sshr v0.4h, v0.4h, #8 193; CHECK-NEXT: abs v0.4h, v0.4h 194; CHECK-NEXT: ret 195entry: 196 %res = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %a, i1 0) 197 ret <4 x i8> %res 198} 199declare <4 x i8> @llvm.abs.v4i8(<4 x i8>, i1) 200 201define <32 x i8> @abs_v32i8(<32 x i8> %a){ 202; CHECK-LABEL: abs_v32i8: 203; CHECK: // %bb.0: // %entry 204; CHECK-NEXT: abs v0.16b, v0.16b 205; CHECK-NEXT: abs v1.16b, v1.16b 206; CHECK-NEXT: ret 207entry: 208 %res = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %a, i1 0) 209 ret <32 x i8> %res 210} 211declare <32 x i8> @llvm.abs.v32i8(<32 x i8>, i1) 212 213define <2 x i16> @abs_v2i16(<2 x i16> %a){ 214; CHECK-LABEL: abs_v2i16: 215; CHECK: // %bb.0: // %entry 216; CHECK-NEXT: shl v0.2s, v0.2s, #16 217; CHECK-NEXT: sshr v0.2s, v0.2s, #16 218; CHECK-NEXT: abs v0.2s, v0.2s 219; CHECK-NEXT: ret 220entry: 221 %res = call <2 x i16> @llvm.abs.v2i16(<2 x i16> %a, i1 0) 222 ret <2 x i16> %res 223} 224declare <2 x i16> @llvm.abs.v2i16(<2 x i16>, i1) 225 226define <16 x i16> @abs_v16i16(<16 x i16> %a){ 227; CHECK-LABEL: abs_v16i16: 228; CHECK: // %bb.0: // %entry 229; CHECK-NEXT: abs v0.8h, v0.8h 230; CHECK-NEXT: abs v1.8h, v1.8h 231; CHECK-NEXT: ret 232entry: 233 %res = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %a, i1 0) 234 ret <16 x i16> %res 235} 236declare <16 x i16> @llvm.abs.v16i16(<16 x i16>, i1) 237 238define <1 x i32> @abs_v1i32(<1 x i32> %a){ 239; CHECK-SD-LABEL: abs_v1i32: 240; CHECK-SD: // %bb.0: // %entry 241; CHECK-SD-NEXT: abs v0.2s, v0.2s 242; CHECK-SD-NEXT: ret 243; 244; CHECK-GI-LABEL: abs_v1i32: 245; CHECK-GI: // %bb.0: // %entry 246; CHECK-GI-NEXT: fmov w8, s0 247; CHECK-GI-NEXT: fmov w9, s0 248; CHECK-GI-NEXT: cmp w8, #0 249; CHECK-GI-NEXT: cneg w8, w9, le 250; CHECK-GI-NEXT: mov v0.s[0], w8 251; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0 252; CHECK-GI-NEXT: ret 253entry: 254 %res = call <1 x i32> @llvm.abs.v1i32(<1 x i32> %a, i1 0) 255 ret <1 x i32> %res 256} 257declare <1 x i32> @llvm.abs.v1i32(<1 x i32>, i1) 258 259define <8 x i32> @abs_v8i32(<8 x i32> %a){ 260; CHECK-LABEL: abs_v8i32: 261; CHECK: // %bb.0: // %entry 262; CHECK-NEXT: abs v0.4s, v0.4s 263; CHECK-NEXT: abs v1.4s, v1.4s 264; CHECK-NEXT: ret 265entry: 266 %res = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %a, i1 0) 267 ret <8 x i32> %res 268} 269declare <8 x i32> @llvm.abs.v8i32(<8 x i32>, i1) 270 271define <4 x i64> @abs_v4i64(<4 x i64> %a){ 272; CHECK-LABEL: abs_v4i64: 273; CHECK: // %bb.0: // %entry 274; CHECK-NEXT: abs v0.2d, v0.2d 275; CHECK-NEXT: abs v1.2d, v1.2d 276; CHECK-NEXT: ret 277entry: 278 %res = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %a, i1 0) 279 ret <4 x i64> %res 280} 281declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1) 282 283define <2 x i128> @abs_v4i128(<2 x i128> %a){ 284; CHECK-SD-LABEL: abs_v4i128: 285; CHECK-SD: // %bb.0: // %entry 286; CHECK-SD-NEXT: asr x8, x1, #63 287; CHECK-SD-NEXT: asr x9, x3, #63 288; CHECK-SD-NEXT: eor x10, x0, x8 289; CHECK-SD-NEXT: eor x11, x1, x8 290; CHECK-SD-NEXT: subs x0, x10, x8 291; CHECK-SD-NEXT: eor x10, x2, x9 292; CHECK-SD-NEXT: sbc x1, x11, x8 293; CHECK-SD-NEXT: eor x8, x3, x9 294; CHECK-SD-NEXT: subs x2, x10, x9 295; CHECK-SD-NEXT: sbc x3, x8, x9 296; CHECK-SD-NEXT: ret 297; 298; CHECK-GI-LABEL: abs_v4i128: 299; CHECK-GI: // %bb.0: // %entry 300; CHECK-GI-NEXT: asr x8, x1, #63 301; CHECK-GI-NEXT: asr x9, x3, #63 302; CHECK-GI-NEXT: adds x10, x0, x8 303; CHECK-GI-NEXT: adc x11, x1, x8 304; CHECK-GI-NEXT: adds x12, x2, x9 305; CHECK-GI-NEXT: eor x0, x10, x8 306; CHECK-GI-NEXT: adc x13, x3, x9 307; CHECK-GI-NEXT: eor x1, x11, x8 308; CHECK-GI-NEXT: eor x2, x12, x9 309; CHECK-GI-NEXT: eor x3, x13, x9 310; CHECK-GI-NEXT: ret 311entry: 312 %res = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %a, i1 0) 313 ret <2 x i128> %res 314} 315declare <2 x i128> @llvm.abs.v2i128(<2 x i128>, i1) 316 317; ===== Vectors with Non-Pow 2 Widths ===== 318 319define <3 x i8> @abs_v3i8(<3 x i8> %a){ 320; CHECK-SD-LABEL: abs_v3i8: 321; CHECK-SD: // %bb.0: // %entry 322; CHECK-SD-NEXT: fmov s0, w0 323; CHECK-SD-NEXT: mov v0.h[1], w1 324; CHECK-SD-NEXT: mov v0.h[2], w2 325; CHECK-SD-NEXT: shl v0.4h, v0.4h, #8 326; CHECK-SD-NEXT: sshr v0.4h, v0.4h, #8 327; CHECK-SD-NEXT: abs v0.4h, v0.4h 328; CHECK-SD-NEXT: umov w0, v0.h[0] 329; CHECK-SD-NEXT: umov w1, v0.h[1] 330; CHECK-SD-NEXT: umov w2, v0.h[2] 331; CHECK-SD-NEXT: ret 332; 333; CHECK-GI-LABEL: abs_v3i8: 334; CHECK-GI: // %bb.0: // %entry 335; CHECK-GI-NEXT: fmov s0, w0 336; CHECK-GI-NEXT: mov v0.b[1], w1 337; CHECK-GI-NEXT: mov v0.b[2], w2 338; CHECK-GI-NEXT: abs v0.8b, v0.8b 339; CHECK-GI-NEXT: umov w0, v0.b[0] 340; CHECK-GI-NEXT: umov w1, v0.b[1] 341; CHECK-GI-NEXT: umov w2, v0.b[2] 342; CHECK-GI-NEXT: ret 343entry: 344 %res = call <3 x i8> @llvm.abs.v3i8(<3 x i8> %a, i1 0) 345 ret <3 x i8> %res 346} 347declare <3 x i8> @llvm.abs.v3i8(<3 x i8>, i1) 348 349define <7 x i8> @abs_v7i8(<7 x i8> %a){ 350; CHECK-LABEL: abs_v7i8: 351; CHECK: // %bb.0: // %entry 352; CHECK-NEXT: abs v0.8b, v0.8b 353; CHECK-NEXT: ret 354entry: 355 %res = call <7 x i8> @llvm.abs.v7i8(<7 x i8> %a, i1 0) 356 ret <7 x i8> %res 357} 358declare <7 x i8> @llvm.abs.v7i8(<7 x i8>, i1) 359 360define <3 x i16> @abs_v3i16(<3 x i16> %a){ 361; CHECK-LABEL: abs_v3i16: 362; CHECK: // %bb.0: // %entry 363; CHECK-NEXT: abs v0.4h, v0.4h 364; CHECK-NEXT: ret 365entry: 366 %res = call <3 x i16> @llvm.abs.v3i16(<3 x i16> %a, i1 0) 367 ret <3 x i16> %res 368} 369declare <3 x i16> @llvm.abs.v3i16(<3 x i16>, i1) 370 371define <7 x i16> @abs_v7i16(<7 x i16> %a){ 372; CHECK-LABEL: abs_v7i16: 373; CHECK: // %bb.0: // %entry 374; CHECK-NEXT: abs v0.8h, v0.8h 375; CHECK-NEXT: ret 376entry: 377 %res = call <7 x i16> @llvm.abs.v7i16(<7 x i16> %a, i1 0) 378 ret <7 x i16> %res 379} 380declare <7 x i16> @llvm.abs.v7i16(<7 x i16>, i1) 381 382define <3 x i32> @abs_v3i32(<3 x i32> %a){ 383; CHECK-LABEL: abs_v3i32: 384; CHECK: // %bb.0: // %entry 385; CHECK-NEXT: abs v0.4s, v0.4s 386; CHECK-NEXT: ret 387entry: 388 %res = call <3 x i32> @llvm.abs.v3i32(<3 x i32> %a, i1 0) 389 ret <3 x i32> %res 390} 391declare <3 x i32> @llvm.abs.v3i32(<3 x i32>, i1) 392