This reverts commit 9c319d5bb4.
Some issues were discovered with the bootstrap builds, which
seem like they were caused by this commit. I'm reverting to investigate.
392 lines
11 KiB
LLVM
392 lines
11 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
|
|
; RUN: llc -mtriple=aarch64-none-linux-gnu %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
|
; RUN: llc -mtriple=aarch64-none-linux-gnu -global-isel %s -o - | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
|
|
|
; ===== Legal Scalars =====
|
|
|
|
define i8 @abs_i8(i8 %a){
|
|
; CHECK-SD-LABEL: abs_i8:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: sxtb w8, w0
|
|
; CHECK-SD-NEXT: cmp w8, #0
|
|
; CHECK-SD-NEXT: cneg w0, w8, mi
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_i8:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: sxtb w8, w0
|
|
; CHECK-GI-NEXT: cmp w8, #0
|
|
; CHECK-GI-NEXT: cneg w0, w0, le
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call i8 @llvm.abs.i8(i8 %a, i1 0)
|
|
ret i8 %res
|
|
}
|
|
declare i8 @llvm.abs.i8(i8, i1)
|
|
|
|
define i16 @abs_i16(i16 %a){
|
|
; CHECK-SD-LABEL: abs_i16:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: sxth w8, w0
|
|
; CHECK-SD-NEXT: cmp w8, #0
|
|
; CHECK-SD-NEXT: cneg w0, w8, mi
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_i16:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: sxth w8, w0
|
|
; CHECK-GI-NEXT: cmp w8, #0
|
|
; CHECK-GI-NEXT: cneg w0, w0, le
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call i16 @llvm.abs.i16(i16 %a, i1 0)
|
|
ret i16 %res
|
|
}
|
|
declare i16 @llvm.abs.i16(i16, i1)
|
|
|
|
define i32 @abs_i32(i32 %a){
|
|
; CHECK-SD-LABEL: abs_i32:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: cmp w0, #0
|
|
; CHECK-SD-NEXT: cneg w0, w0, mi
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_i32:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: cmp w0, #0
|
|
; CHECK-GI-NEXT: cneg w0, w0, le
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call i32 @llvm.abs.i32(i32 %a, i1 0)
|
|
ret i32 %res
|
|
}
|
|
declare i32 @llvm.abs.i32(i32, i1)
|
|
|
|
define i64 @abs_i64(i64 %a){
|
|
; CHECK-SD-LABEL: abs_i64:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: cmp x0, #0
|
|
; CHECK-SD-NEXT: cneg x0, x0, mi
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_i64:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: cmp x0, #0
|
|
; CHECK-GI-NEXT: cneg x0, x0, le
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call i64 @llvm.abs.i64(i64 %a, i1 0)
|
|
ret i64 %res
|
|
}
|
|
declare i64 @llvm.abs.i64(i64, i1)
|
|
|
|
define i128 @abs_i128(i128 %a){
|
|
; CHECK-SD-LABEL: abs_i128:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: asr x8, x1, #63
|
|
; CHECK-SD-NEXT: eor x9, x0, x8
|
|
; CHECK-SD-NEXT: eor x10, x1, x8
|
|
; CHECK-SD-NEXT: subs x0, x9, x8
|
|
; CHECK-SD-NEXT: sbc x1, x10, x8
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_i128:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: asr x8, x1, #63
|
|
; CHECK-GI-NEXT: adds x9, x0, x8
|
|
; CHECK-GI-NEXT: adc x10, x1, x8
|
|
; CHECK-GI-NEXT: eor x0, x9, x8
|
|
; CHECK-GI-NEXT: eor x1, x10, x8
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call i128 @llvm.abs.i128(i128 %a, i1 0)
|
|
ret i128 %res
|
|
}
|
|
declare i128 @llvm.abs.i128(i128, i1)
|
|
|
|
; ===== Legal Vector Types =====
|
|
|
|
define <8 x i8> @abs_v8i8(<8 x i8> %a){
|
|
; CHECK-LABEL: abs_v8i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.8b, v0.8b
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <8 x i8> @llvm.abs.v8i8(<8 x i8> %a, i1 0)
|
|
ret <8 x i8> %res
|
|
}
|
|
declare <8 x i8> @llvm.abs.v8i8(<8 x i8>, i1)
|
|
|
|
define <16 x i8> @abs_v16i8(<16 x i8> %a){
|
|
; CHECK-LABEL: abs_v16i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.16b, v0.16b
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <16 x i8> @llvm.abs.v16i8(<16 x i8> %a, i1 0)
|
|
ret <16 x i8> %res
|
|
}
|
|
declare <16 x i8> @llvm.abs.v16i8(<16 x i8>, i1)
|
|
|
|
define <4 x i16> @abs_v4i16(<4 x i16> %a){
|
|
; CHECK-LABEL: abs_v4i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.4h, v0.4h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <4 x i16> @llvm.abs.v4i16(<4 x i16> %a, i1 0)
|
|
ret <4 x i16> %res
|
|
}
|
|
declare <4 x i16> @llvm.abs.v4i16(<4 x i16>, i1)
|
|
|
|
define <8 x i16> @abs_v8i16(<8 x i16> %a){
|
|
; CHECK-LABEL: abs_v8i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.8h, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <8 x i16> @llvm.abs.v8i16(<8 x i16> %a, i1 0)
|
|
ret <8 x i16> %res
|
|
}
|
|
declare <8 x i16> @llvm.abs.v8i16(<8 x i16>, i1)
|
|
|
|
define <2 x i32> @abs_v2i32(<2 x i32> %a){
|
|
; CHECK-LABEL: abs_v2i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.2s, v0.2s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <2 x i32> @llvm.abs.v2i32(<2 x i32> %a, i1 0)
|
|
ret <2 x i32> %res
|
|
}
|
|
declare <2 x i32> @llvm.abs.v2i32(<2 x i32>, i1)
|
|
|
|
define <4 x i32> @abs_v4i32(<4 x i32> %a){
|
|
; CHECK-LABEL: abs_v4i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.4s, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <4 x i32> @llvm.abs.v4i32(<4 x i32> %a, i1 0)
|
|
ret <4 x i32> %res
|
|
}
|
|
declare <4 x i32> @llvm.abs.v4i32(<4 x i32>, i1)
|
|
|
|
define <2 x i64> @abs_v2i64(<2 x i64> %a){
|
|
; CHECK-LABEL: abs_v2i64:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.2d, v0.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <2 x i64> @llvm.abs.v2i64(<2 x i64> %a, i1 0)
|
|
ret <2 x i64> %res
|
|
}
|
|
declare <2 x i64> @llvm.abs.v2i64(<2 x i64>, i1)
|
|
|
|
; ===== Smaller/Larger Width Vectors with Legal Element Sizes =====
|
|
|
|
define <4 x i8> @abs_v4i8(<4 x i8> %a){
|
|
; CHECK-LABEL: abs_v4i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: shl v0.4h, v0.4h, #8
|
|
; CHECK-NEXT: sshr v0.4h, v0.4h, #8
|
|
; CHECK-NEXT: abs v0.4h, v0.4h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <4 x i8> @llvm.abs.v4i8(<4 x i8> %a, i1 0)
|
|
ret <4 x i8> %res
|
|
}
|
|
declare <4 x i8> @llvm.abs.v4i8(<4 x i8>, i1)
|
|
|
|
define <32 x i8> @abs_v32i8(<32 x i8> %a){
|
|
; CHECK-LABEL: abs_v32i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.16b, v0.16b
|
|
; CHECK-NEXT: abs v1.16b, v1.16b
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <32 x i8> @llvm.abs.v32i8(<32 x i8> %a, i1 0)
|
|
ret <32 x i8> %res
|
|
}
|
|
declare <32 x i8> @llvm.abs.v32i8(<32 x i8>, i1)
|
|
|
|
define <2 x i16> @abs_v2i16(<2 x i16> %a){
|
|
; CHECK-LABEL: abs_v2i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: shl v0.2s, v0.2s, #16
|
|
; CHECK-NEXT: sshr v0.2s, v0.2s, #16
|
|
; CHECK-NEXT: abs v0.2s, v0.2s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <2 x i16> @llvm.abs.v2i16(<2 x i16> %a, i1 0)
|
|
ret <2 x i16> %res
|
|
}
|
|
declare <2 x i16> @llvm.abs.v2i16(<2 x i16>, i1)
|
|
|
|
define <16 x i16> @abs_v16i16(<16 x i16> %a){
|
|
; CHECK-LABEL: abs_v16i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.8h, v0.8h
|
|
; CHECK-NEXT: abs v1.8h, v1.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <16 x i16> @llvm.abs.v16i16(<16 x i16> %a, i1 0)
|
|
ret <16 x i16> %res
|
|
}
|
|
declare <16 x i16> @llvm.abs.v16i16(<16 x i16>, i1)
|
|
|
|
define <1 x i32> @abs_v1i32(<1 x i32> %a){
|
|
; CHECK-SD-LABEL: abs_v1i32:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: abs v0.2s, v0.2s
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_v1i32:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: fmov w8, s0
|
|
; CHECK-GI-NEXT: fmov w9, s0
|
|
; CHECK-GI-NEXT: cmp w8, #0
|
|
; CHECK-GI-NEXT: cneg w8, w9, le
|
|
; CHECK-GI-NEXT: mov v0.s[0], w8
|
|
; CHECK-GI-NEXT: // kill: def $d0 killed $d0 killed $q0
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call <1 x i32> @llvm.abs.v1i32(<1 x i32> %a, i1 0)
|
|
ret <1 x i32> %res
|
|
}
|
|
declare <1 x i32> @llvm.abs.v1i32(<1 x i32>, i1)
|
|
|
|
define <8 x i32> @abs_v8i32(<8 x i32> %a){
|
|
; CHECK-LABEL: abs_v8i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.4s, v0.4s
|
|
; CHECK-NEXT: abs v1.4s, v1.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <8 x i32> @llvm.abs.v8i32(<8 x i32> %a, i1 0)
|
|
ret <8 x i32> %res
|
|
}
|
|
declare <8 x i32> @llvm.abs.v8i32(<8 x i32>, i1)
|
|
|
|
define <4 x i64> @abs_v4i64(<4 x i64> %a){
|
|
; CHECK-LABEL: abs_v4i64:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.2d, v0.2d
|
|
; CHECK-NEXT: abs v1.2d, v1.2d
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <4 x i64> @llvm.abs.v4i64(<4 x i64> %a, i1 0)
|
|
ret <4 x i64> %res
|
|
}
|
|
declare <4 x i64> @llvm.abs.v4i64(<4 x i64>, i1)
|
|
|
|
define <2 x i128> @abs_v4i128(<2 x i128> %a){
|
|
; CHECK-SD-LABEL: abs_v4i128:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: asr x8, x1, #63
|
|
; CHECK-SD-NEXT: asr x9, x3, #63
|
|
; CHECK-SD-NEXT: eor x10, x0, x8
|
|
; CHECK-SD-NEXT: eor x11, x1, x8
|
|
; CHECK-SD-NEXT: subs x0, x10, x8
|
|
; CHECK-SD-NEXT: eor x10, x2, x9
|
|
; CHECK-SD-NEXT: sbc x1, x11, x8
|
|
; CHECK-SD-NEXT: eor x8, x3, x9
|
|
; CHECK-SD-NEXT: subs x2, x10, x9
|
|
; CHECK-SD-NEXT: sbc x3, x8, x9
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_v4i128:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: asr x8, x1, #63
|
|
; CHECK-GI-NEXT: asr x9, x3, #63
|
|
; CHECK-GI-NEXT: adds x10, x0, x8
|
|
; CHECK-GI-NEXT: adc x11, x1, x8
|
|
; CHECK-GI-NEXT: adds x12, x2, x9
|
|
; CHECK-GI-NEXT: eor x0, x10, x8
|
|
; CHECK-GI-NEXT: adc x13, x3, x9
|
|
; CHECK-GI-NEXT: eor x1, x11, x8
|
|
; CHECK-GI-NEXT: eor x2, x12, x9
|
|
; CHECK-GI-NEXT: eor x3, x13, x9
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call <2 x i128> @llvm.abs.v2i128(<2 x i128> %a, i1 0)
|
|
ret <2 x i128> %res
|
|
}
|
|
declare <2 x i128> @llvm.abs.v2i128(<2 x i128>, i1)
|
|
|
|
; ===== Vectors with Non-Pow 2 Widths =====
|
|
|
|
define <3 x i8> @abs_v3i8(<3 x i8> %a){
|
|
; CHECK-SD-LABEL: abs_v3i8:
|
|
; CHECK-SD: // %bb.0: // %entry
|
|
; CHECK-SD-NEXT: fmov s0, w0
|
|
; CHECK-SD-NEXT: mov v0.h[1], w1
|
|
; CHECK-SD-NEXT: mov v0.h[2], w2
|
|
; CHECK-SD-NEXT: shl v0.4h, v0.4h, #8
|
|
; CHECK-SD-NEXT: sshr v0.4h, v0.4h, #8
|
|
; CHECK-SD-NEXT: abs v0.4h, v0.4h
|
|
; CHECK-SD-NEXT: umov w0, v0.h[0]
|
|
; CHECK-SD-NEXT: umov w1, v0.h[1]
|
|
; CHECK-SD-NEXT: umov w2, v0.h[2]
|
|
; CHECK-SD-NEXT: ret
|
|
;
|
|
; CHECK-GI-LABEL: abs_v3i8:
|
|
; CHECK-GI: // %bb.0: // %entry
|
|
; CHECK-GI-NEXT: fmov s0, w0
|
|
; CHECK-GI-NEXT: mov v0.b[1], w1
|
|
; CHECK-GI-NEXT: mov v0.b[2], w2
|
|
; CHECK-GI-NEXT: abs v0.8b, v0.8b
|
|
; CHECK-GI-NEXT: umov w0, v0.b[0]
|
|
; CHECK-GI-NEXT: umov w1, v0.b[1]
|
|
; CHECK-GI-NEXT: umov w2, v0.b[2]
|
|
; CHECK-GI-NEXT: ret
|
|
entry:
|
|
%res = call <3 x i8> @llvm.abs.v3i8(<3 x i8> %a, i1 0)
|
|
ret <3 x i8> %res
|
|
}
|
|
declare <3 x i8> @llvm.abs.v3i8(<3 x i8>, i1)
|
|
|
|
define <7 x i8> @abs_v7i8(<7 x i8> %a){
|
|
; CHECK-LABEL: abs_v7i8:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.8b, v0.8b
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <7 x i8> @llvm.abs.v7i8(<7 x i8> %a, i1 0)
|
|
ret <7 x i8> %res
|
|
}
|
|
declare <7 x i8> @llvm.abs.v7i8(<7 x i8>, i1)
|
|
|
|
define <3 x i16> @abs_v3i16(<3 x i16> %a){
|
|
; CHECK-LABEL: abs_v3i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.4h, v0.4h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <3 x i16> @llvm.abs.v3i16(<3 x i16> %a, i1 0)
|
|
ret <3 x i16> %res
|
|
}
|
|
declare <3 x i16> @llvm.abs.v3i16(<3 x i16>, i1)
|
|
|
|
define <7 x i16> @abs_v7i16(<7 x i16> %a){
|
|
; CHECK-LABEL: abs_v7i16:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.8h, v0.8h
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <7 x i16> @llvm.abs.v7i16(<7 x i16> %a, i1 0)
|
|
ret <7 x i16> %res
|
|
}
|
|
declare <7 x i16> @llvm.abs.v7i16(<7 x i16>, i1)
|
|
|
|
define <3 x i32> @abs_v3i32(<3 x i32> %a){
|
|
; CHECK-LABEL: abs_v3i32:
|
|
; CHECK: // %bb.0: // %entry
|
|
; CHECK-NEXT: abs v0.4s, v0.4s
|
|
; CHECK-NEXT: ret
|
|
entry:
|
|
%res = call <3 x i32> @llvm.abs.v3i32(<3 x i32> %a, i1 0)
|
|
ret <3 x i32> %res
|
|
}
|
|
declare <3 x i32> @llvm.abs.v3i32(<3 x i32>, i1)
|