[AArch64][GlobalISel] Add extra GISel test coverage. NFC
This is essentially from performAddSubCombine. addsub.ll has been cleaned up a little in the process.
This commit is contained in:
parent
c5327b935b
commit
2ec91a5ec4
@ -1,5 +1,6 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=aarch64-- -o - < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-- -o - < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-- -global-isel -o - < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
; Verify that we can fold csneg/csel into csinc instruction.
|
||||
|
||||
@ -8,12 +9,20 @@ target triple = "aarch64-unknown-linux-gnu"
|
||||
|
||||
; char csinc1 (char a, char b) { return !a ? b+1 : b+3; }
|
||||
define i8 @csinc1(i8 %a, i8 %b) local_unnamed_addr #0 {
|
||||
; CHECK-LABEL: csinc1:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: tst w0, #0xff
|
||||
; CHECK-NEXT: add w8, w1, #3
|
||||
; CHECK-NEXT: csinc w0, w8, w1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: csinc1:
|
||||
; CHECK-SD: // %bb.0: // %entry
|
||||
; CHECK-SD-NEXT: tst w0, #0xff
|
||||
; CHECK-SD-NEXT: add w8, w1, #3
|
||||
; CHECK-SD-NEXT: csinc w0, w8, w1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: csinc1:
|
||||
; CHECK-GI: // %bb.0: // %entry
|
||||
; CHECK-GI-NEXT: mov w8, #3 // =0x3
|
||||
; CHECK-GI-NEXT: tst w0, #0xff
|
||||
; CHECK-GI-NEXT: csinc w8, w8, wzr, ne
|
||||
; CHECK-GI-NEXT: add w0, w8, w1
|
||||
; CHECK-GI-NEXT: ret
|
||||
entry:
|
||||
%tobool.not = icmp eq i8 %a, 0
|
||||
%cond.v = select i1 %tobool.not, i8 1, i8 3
|
||||
@ -23,12 +32,20 @@ entry:
|
||||
|
||||
; short csinc2 (short a, short b) { return !a ? b+1 : b+3; }
|
||||
define i16 @csinc2(i16 %a, i16 %b) local_unnamed_addr #0 {
|
||||
; CHECK-LABEL: csinc2:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: tst w0, #0xffff
|
||||
; CHECK-NEXT: add w8, w1, #3
|
||||
; CHECK-NEXT: csinc w0, w8, w1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: csinc2:
|
||||
; CHECK-SD: // %bb.0: // %entry
|
||||
; CHECK-SD-NEXT: tst w0, #0xffff
|
||||
; CHECK-SD-NEXT: add w8, w1, #3
|
||||
; CHECK-SD-NEXT: csinc w0, w8, w1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: csinc2:
|
||||
; CHECK-GI: // %bb.0: // %entry
|
||||
; CHECK-GI-NEXT: mov w8, #3 // =0x3
|
||||
; CHECK-GI-NEXT: tst w0, #0xffff
|
||||
; CHECK-GI-NEXT: csinc w8, w8, wzr, ne
|
||||
; CHECK-GI-NEXT: add w0, w8, w1
|
||||
; CHECK-GI-NEXT: ret
|
||||
entry:
|
||||
%tobool.not = icmp eq i16 %a, 0
|
||||
%cond.v = select i1 %tobool.not, i16 1, i16 3
|
||||
@ -38,12 +55,20 @@ entry:
|
||||
|
||||
; int csinc3 (int a, int b) { return !a ? b+1 : b+3; }
|
||||
define i32 @csinc3(i32 %a, i32 %b) local_unnamed_addr #0 {
|
||||
; CHECK-LABEL: csinc3:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: cmp w0, #0
|
||||
; CHECK-NEXT: add w8, w1, #3
|
||||
; CHECK-NEXT: csinc w0, w8, w1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: csinc3:
|
||||
; CHECK-SD: // %bb.0: // %entry
|
||||
; CHECK-SD-NEXT: cmp w0, #0
|
||||
; CHECK-SD-NEXT: add w8, w1, #3
|
||||
; CHECK-SD-NEXT: csinc w0, w8, w1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: csinc3:
|
||||
; CHECK-GI: // %bb.0: // %entry
|
||||
; CHECK-GI-NEXT: mov w8, #3 // =0x3
|
||||
; CHECK-GI-NEXT: cmp w0, #0
|
||||
; CHECK-GI-NEXT: csinc w8, w8, wzr, ne
|
||||
; CHECK-GI-NEXT: add w0, w8, w1
|
||||
; CHECK-GI-NEXT: ret
|
||||
entry:
|
||||
%tobool.not = icmp eq i32 %a, 0
|
||||
%cond.v = select i1 %tobool.not, i32 1, i32 3
|
||||
@ -53,12 +78,20 @@ entry:
|
||||
|
||||
; long long csinc4 (long long a, long long b) { return !a ? b+1 : b+3; }
|
||||
define i64 @csinc4(i64 %a, i64 %b) local_unnamed_addr #0 {
|
||||
; CHECK-LABEL: csinc4:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: cmp x0, #0
|
||||
; CHECK-NEXT: add x8, x1, #3
|
||||
; CHECK-NEXT: csinc x0, x8, x1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: csinc4:
|
||||
; CHECK-SD: // %bb.0: // %entry
|
||||
; CHECK-SD-NEXT: cmp x0, #0
|
||||
; CHECK-SD-NEXT: add x8, x1, #3
|
||||
; CHECK-SD-NEXT: csinc x0, x8, x1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: csinc4:
|
||||
; CHECK-GI: // %bb.0: // %entry
|
||||
; CHECK-GI-NEXT: mov w8, #3 // =0x3
|
||||
; CHECK-GI-NEXT: cmp x0, #0
|
||||
; CHECK-GI-NEXT: csinc x8, x8, xzr, ne
|
||||
; CHECK-GI-NEXT: add x0, x8, x1
|
||||
; CHECK-GI-NEXT: ret
|
||||
entry:
|
||||
%tobool.not = icmp eq i64 %a, 0
|
||||
%cond.v = select i1 %tobool.not, i64 1, i64 3
|
||||
@ -68,12 +101,21 @@ entry:
|
||||
|
||||
; long long csinc8 (long long a, long long b) { return a ? b-1 : b+1; }
|
||||
define i64 @csinc8(i64 %a, i64 %b) {
|
||||
; CHECK-LABEL: csinc8:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: sub x8, x1, #1
|
||||
; CHECK-NEXT: cmp x0, #0
|
||||
; CHECK-NEXT: csinc x0, x8, x1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: csinc8:
|
||||
; CHECK-SD: // %bb.0: // %entry
|
||||
; CHECK-SD-NEXT: sub x8, x1, #1
|
||||
; CHECK-SD-NEXT: cmp x0, #0
|
||||
; CHECK-SD-NEXT: csinc x0, x8, x1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: csinc8:
|
||||
; CHECK-GI: // %bb.0: // %entry
|
||||
; CHECK-GI-NEXT: cmp x0, #0
|
||||
; CHECK-GI-NEXT: cset w8, ne
|
||||
; CHECK-GI-NEXT: sbfx x8, x8, #0, #1
|
||||
; CHECK-GI-NEXT: orr x8, x8, #0x1
|
||||
; CHECK-GI-NEXT: add x0, x8, x1
|
||||
; CHECK-GI-NEXT: ret
|
||||
entry:
|
||||
%tobool.not = icmp eq i64 %a, 0
|
||||
%cond.v = select i1 %tobool.not, i64 1, i64 -1
|
||||
@ -83,15 +125,26 @@ entry:
|
||||
|
||||
; long long csinc9 (long long a, long long b) { return a ? b+1 : b-1; }
|
||||
define i64 @csinc9(i64 %a, i64 %b) {
|
||||
; CHECK-LABEL: csinc9:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: sub x8, x1, #1
|
||||
; CHECK-NEXT: cmp x0, #0
|
||||
; CHECK-NEXT: csinc x0, x8, x1, eq
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: csinc9:
|
||||
; CHECK-SD: // %bb.0: // %entry
|
||||
; CHECK-SD-NEXT: sub x8, x1, #1
|
||||
; CHECK-SD-NEXT: cmp x0, #0
|
||||
; CHECK-SD-NEXT: csinc x0, x8, x1, eq
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: csinc9:
|
||||
; CHECK-GI: // %bb.0: // %entry
|
||||
; CHECK-GI-NEXT: cmp x0, #0
|
||||
; CHECK-GI-NEXT: cset w8, eq
|
||||
; CHECK-GI-NEXT: sbfx x8, x8, #0, #1
|
||||
; CHECK-GI-NEXT: orr x8, x8, #0x1
|
||||
; CHECK-GI-NEXT: add x0, x8, x1
|
||||
; CHECK-GI-NEXT: ret
|
||||
entry:
|
||||
%tobool.not = icmp eq i64 %a, 0
|
||||
%cond.v = select i1 %tobool.not, i64 -1, i64 1
|
||||
%cond = add nsw i64 %cond.v, %b
|
||||
ret i64 %cond
|
||||
}
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; CHECK: {{.*}}
|
||||
|
@ -1,13 +1,21 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 2
|
||||
; RUN: llc < %s -mtriple=arm64-eabi | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-none-elf -mattr=+aes < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-elf -mattr=+aes -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
define i64 @add_i64_ext_load(<1 x i64> %A, ptr %B) nounwind {
|
||||
; CHECK-LABEL: add_i64_ext_load:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr d1, [x0]
|
||||
; CHECK-NEXT: add d0, d0, d1
|
||||
; CHECK-NEXT: fmov x0, d0
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: add_i64_ext_load:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: ldr d1, [x0]
|
||||
; CHECK-SD-NEXT: add d0, d0, d1
|
||||
; CHECK-SD-NEXT: fmov x0, d0
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: add_i64_ext_load:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: fmov x9, d0
|
||||
; CHECK-GI-NEXT: ldr x8, [x0]
|
||||
; CHECK-GI-NEXT: add x0, x9, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i64> %A, i32 0
|
||||
%b = load i64, ptr %B
|
||||
%c = add i64 %a, %b
|
||||
@ -15,12 +23,19 @@ define i64 @add_i64_ext_load(<1 x i64> %A, ptr %B) nounwind {
|
||||
}
|
||||
|
||||
define i64 @sub_i64_ext_load(<1 x i64> %A, ptr %B) nounwind {
|
||||
; CHECK-LABEL: sub_i64_ext_load:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr d1, [x0]
|
||||
; CHECK-NEXT: sub d0, d0, d1
|
||||
; CHECK-NEXT: fmov x0, d0
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: sub_i64_ext_load:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: ldr d1, [x0]
|
||||
; CHECK-SD-NEXT: sub d0, d0, d1
|
||||
; CHECK-SD-NEXT: fmov x0, d0
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: sub_i64_ext_load:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: fmov x9, d0
|
||||
; CHECK-GI-NEXT: ldr x8, [x0]
|
||||
; CHECK-GI-NEXT: sub x0, x9, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i64> %A, i32 0
|
||||
%b = load i64, ptr %B
|
||||
%c = sub i64 %a, %b
|
||||
@ -28,12 +43,20 @@ define i64 @sub_i64_ext_load(<1 x i64> %A, ptr %B) nounwind {
|
||||
}
|
||||
|
||||
define void @add_i64_ext_load_store(<1 x i64> %A, ptr %B) nounwind {
|
||||
; CHECK-LABEL: add_i64_ext_load_store:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ldr d1, [x0]
|
||||
; CHECK-NEXT: add d0, d0, d1
|
||||
; CHECK-NEXT: str d0, [x0]
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: add_i64_ext_load_store:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: ldr d1, [x0]
|
||||
; CHECK-SD-NEXT: add d0, d0, d1
|
||||
; CHECK-SD-NEXT: str d0, [x0]
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: add_i64_ext_load_store:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: fmov x9, d0
|
||||
; CHECK-GI-NEXT: ldr x8, [x0]
|
||||
; CHECK-GI-NEXT: add x8, x9, x8
|
||||
; CHECK-GI-NEXT: str x8, [x0]
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i64> %A, i32 0
|
||||
%b = load i64, ptr %B
|
||||
%c = add i64 %a, %b
|
||||
@ -55,11 +78,18 @@ define i64 @add_v2i64_ext_load(<2 x i64> %A, ptr %B) nounwind {
|
||||
}
|
||||
|
||||
define i64 @add_i64_ext_ext(<1 x i64> %A, <1 x i64> %B) nounwind {
|
||||
; CHECK-LABEL: add_i64_ext_ext:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add d0, d0, d1
|
||||
; CHECK-NEXT: fmov x0, d0
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: add_i64_ext_ext:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: add d0, d0, d1
|
||||
; CHECK-SD-NEXT: fmov x0, d0
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: add_i64_ext_ext:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: fmov x8, d0
|
||||
; CHECK-GI-NEXT: fmov x9, d1
|
||||
; CHECK-GI-NEXT: add x0, x8, x9
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i64> %A, i32 0
|
||||
%b = extractelement <1 x i64> %B, i32 0
|
||||
%c = add i64 %a, %b
|
||||
@ -67,13 +97,20 @@ define i64 @add_i64_ext_ext(<1 x i64> %A, <1 x i64> %B) nounwind {
|
||||
}
|
||||
|
||||
define i32 @add_i32_ext_load(<1 x i32> %A, ptr %B) nounwind {
|
||||
; CHECK-LABEL: add_i32_ext_load:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: // kill: def $d0 killed $d0 def $q0
|
||||
; CHECK-NEXT: fmov w9, s0
|
||||
; CHECK-NEXT: ldr w8, [x0]
|
||||
; CHECK-NEXT: add w0, w9, w8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: add_i32_ext_load:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: // kill: def $d0 killed $d0 def $q0
|
||||
; CHECK-SD-NEXT: fmov w9, s0
|
||||
; CHECK-SD-NEXT: ldr w8, [x0]
|
||||
; CHECK-SD-NEXT: add w0, w9, w8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: add_i32_ext_load:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: fmov w9, s0
|
||||
; CHECK-GI-NEXT: ldr w8, [x0]
|
||||
; CHECK-GI-NEXT: add w0, w9, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i32> %A, i32 0
|
||||
%b = load i32, ptr %B
|
||||
%c = add i32 %a, %b
|
||||
@ -81,13 +118,22 @@ define i32 @add_i32_ext_load(<1 x i32> %A, ptr %B) nounwind {
|
||||
}
|
||||
|
||||
define i64 @add_i64_ext_ext_test1(<1 x i64> %A, <2 x i64> %B) nounwind {
|
||||
; CHECK-LABEL: add_i64_ext_ext_test1:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ext v2.16b, v1.16b, v1.16b, #8
|
||||
; CHECK-NEXT: add d0, d0, d1
|
||||
; CHECK-NEXT: add d0, d0, d2
|
||||
; CHECK-NEXT: fmov x0, d0
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: add_i64_ext_ext_test1:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: ext v2.16b, v1.16b, v1.16b, #8
|
||||
; CHECK-SD-NEXT: add d0, d0, d1
|
||||
; CHECK-SD-NEXT: add d0, d0, d2
|
||||
; CHECK-SD-NEXT: fmov x0, d0
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: add_i64_ext_ext_test1:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mov x8, v1.d[1]
|
||||
; CHECK-GI-NEXT: fmov x9, d0
|
||||
; CHECK-GI-NEXT: fmov x10, d1
|
||||
; CHECK-GI-NEXT: add x9, x9, x10
|
||||
; CHECK-GI-NEXT: add x0, x9, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i64> %A, i32 0
|
||||
%b = extractelement <2 x i64> %B, i32 0
|
||||
%c = extractelement <2 x i64> %B, i32 1
|
||||
@ -97,13 +143,22 @@ define i64 @add_i64_ext_ext_test1(<1 x i64> %A, <2 x i64> %B) nounwind {
|
||||
}
|
||||
|
||||
define i64 @sub_i64_ext_ext_test1(<1 x i64> %A, <2 x i64> %B) nounwind {
|
||||
; CHECK-LABEL: sub_i64_ext_ext_test1:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: ext v2.16b, v1.16b, v1.16b, #8
|
||||
; CHECK-NEXT: sub d0, d0, d1
|
||||
; CHECK-NEXT: sub d0, d0, d2
|
||||
; CHECK-NEXT: fmov x0, d0
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: sub_i64_ext_ext_test1:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: ext v2.16b, v1.16b, v1.16b, #8
|
||||
; CHECK-SD-NEXT: sub d0, d0, d1
|
||||
; CHECK-SD-NEXT: sub d0, d0, d2
|
||||
; CHECK-SD-NEXT: fmov x0, d0
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: sub_i64_ext_ext_test1:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mov x8, v1.d[1]
|
||||
; CHECK-GI-NEXT: fmov x9, d0
|
||||
; CHECK-GI-NEXT: fmov x10, d1
|
||||
; CHECK-GI-NEXT: sub x9, x9, x10
|
||||
; CHECK-GI-NEXT: sub x0, x9, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%a = extractelement <1 x i64> %A, i32 0
|
||||
%b = extractelement <2 x i64> %B, i32 0
|
||||
%c = extractelement <2 x i64> %B, i32 1
|
||||
|
@ -1,50 +1,26 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-linux-gnu -verify-machineinstrs | FileCheck %s
|
||||
|
||||
; Note that this should be refactored (for efficiency if nothing else)
|
||||
; when the PCS is implemented so we don't have to worry about the
|
||||
; loads and stores.
|
||||
|
||||
@var_i32 = global i32 42
|
||||
@var2_i32 = global i32 43
|
||||
@var_i64 = global i64 0
|
||||
; RUN: llc -mtriple=aarch64-none-elf < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-elf -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
; Add pure 12-bit immediates:
|
||||
define void @add_small() {
|
||||
; CHECK-LABEL: add_small:
|
||||
define i32 @add_small_i32(i32 %val32) {
|
||||
; CHECK-LABEL: add_small_i32:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: adrp x8, :got:var_i32
|
||||
; CHECK-NEXT: adrp x9, :got:var_i64
|
||||
; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32]
|
||||
; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64]
|
||||
; CHECK-NEXT: ldr w10, [x8]
|
||||
; CHECK-NEXT: ldr x11, [x9]
|
||||
; CHECK-NEXT: add w10, w10, #4095
|
||||
; CHECK-NEXT: add x11, x11, #52
|
||||
; CHECK-NEXT: str w10, [x8]
|
||||
; CHECK-NEXT: str x11, [x9]
|
||||
; CHECK-NEXT: add w0, w0, #4095
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
%val32 = load i32, ptr @var_i32
|
||||
%newval32 = add i32 %val32, 4095
|
||||
store i32 %newval32, ptr @var_i32
|
||||
|
||||
%val64 = load i64, ptr @var_i64
|
||||
%newval64 = add i64 %val64, 52
|
||||
store i64 %newval64, ptr @var_i64
|
||||
|
||||
ret void
|
||||
ret i32 %newval32
|
||||
}
|
||||
|
||||
define i64 @add_small_i64(i64 %val64) {
|
||||
; CHECK-LABEL: add_small_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add x0, x0, #52
|
||||
; CHECK-NEXT: ret
|
||||
%newval64 = add i64 %val64, 52
|
||||
ret i64 %newval64
|
||||
}
|
||||
|
||||
; Make sure we grab the imm variant when the register operand
|
||||
; can be implicitly zero-extend.
|
||||
; We used to generate something horrible like this:
|
||||
; wA = ldrb
|
||||
; xB = ldimm 12
|
||||
; xC = add xB, wA, uxtb
|
||||
; whereas this can be achieved with:
|
||||
; wA = ldrb
|
||||
; xC = add xA, #12 ; <- xA implicitly zero extend wA.
|
||||
define void @add_small_imm(ptr %p, ptr %q, i32 %b, ptr %addr) {
|
||||
; CHECK-LABEL: add_small_imm:
|
||||
; CHECK: // %bb.0: // %entry
|
||||
@ -55,98 +31,71 @@ define void @add_small_imm(ptr %p, ptr %q, i32 %b, ptr %addr) {
|
||||
; CHECK-NEXT: str x8, [x1]
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
|
||||
%t = load i8, ptr %p
|
||||
%promoted = zext i8 %t to i64
|
||||
%zextt = zext i8 %t to i32
|
||||
%add = add nuw i32 %zextt, %b
|
||||
|
||||
%add2 = add nuw i64 %promoted, 12
|
||||
store i32 %add, ptr %addr
|
||||
|
||||
store i64 %add2, ptr %q
|
||||
ret void
|
||||
}
|
||||
|
||||
; Add 12-bit immediates, shifted left by 12 bits
|
||||
define void @add_med() {
|
||||
; CHECK-LABEL: add_med:
|
||||
define i32 @add_med_i32(i32 %val32) {
|
||||
; CHECK-LABEL: add_med_i32:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: adrp x8, :got:var_i32
|
||||
; CHECK-NEXT: adrp x9, :got:var_i64
|
||||
; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32]
|
||||
; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64]
|
||||
; CHECK-NEXT: ldr w10, [x8]
|
||||
; CHECK-NEXT: ldr x11, [x9]
|
||||
; CHECK-NEXT: add w10, w10, #3567, lsl #12 // =14610432
|
||||
; CHECK-NEXT: add x11, x11, #4095, lsl #12 // =16773120
|
||||
; CHECK-NEXT: str w10, [x8]
|
||||
; CHECK-NEXT: str x11, [x9]
|
||||
; CHECK-NEXT: add w0, w0, #3567, lsl #12 // =14610432
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
%val32 = load i32, ptr @var_i32
|
||||
%newval32 = add i32 %val32, 14610432 ; =0xdef000
|
||||
store i32 %newval32, ptr @var_i32
|
||||
ret i32 %newval32
|
||||
}
|
||||
|
||||
%val64 = load i64, ptr @var_i64
|
||||
define i64 @add_med_i64(i64 %val64) {
|
||||
; CHECK-LABEL: add_med_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: add x0, x0, #4095, lsl #12 // =16773120
|
||||
; CHECK-NEXT: ret
|
||||
%newval64 = add i64 %val64, 16773120 ; =0xfff000
|
||||
store i64 %newval64, ptr @var_i64
|
||||
|
||||
ret void
|
||||
ret i64 %newval64
|
||||
}
|
||||
|
||||
; Subtract 12-bit immediates
|
||||
define void @sub_small() {
|
||||
; CHECK-LABEL: sub_small:
|
||||
define i32 @sub_small_i32(i32 %val32) {
|
||||
; CHECK-LABEL: sub_small_i32:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: adrp x8, :got:var_i32
|
||||
; CHECK-NEXT: adrp x9, :got:var_i64
|
||||
; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32]
|
||||
; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64]
|
||||
; CHECK-NEXT: ldr w10, [x8]
|
||||
; CHECK-NEXT: ldr x11, [x9]
|
||||
; CHECK-NEXT: sub w10, w10, #4095
|
||||
; CHECK-NEXT: sub x11, x11, #52
|
||||
; CHECK-NEXT: str w10, [x8]
|
||||
; CHECK-NEXT: str x11, [x9]
|
||||
; CHECK-NEXT: sub w0, w0, #4095
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
%val32 = load i32, ptr @var_i32
|
||||
%newval32 = sub i32 %val32, 4095
|
||||
store i32 %newval32, ptr @var_i32
|
||||
ret i32 %newval32
|
||||
}
|
||||
|
||||
%val64 = load i64, ptr @var_i64
|
||||
define i64 @sub_small_i64(i64 %val64) {
|
||||
; CHECK-LABEL: sub_small_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub x0, x0, #52
|
||||
; CHECK-NEXT: ret
|
||||
%newval64 = sub i64 %val64, 52
|
||||
store i64 %newval64, ptr @var_i64
|
||||
|
||||
ret void
|
||||
ret i64 %newval64
|
||||
}
|
||||
|
||||
; Subtract 12-bit immediates, shifted left by 12 bits
|
||||
define void @sub_med() {
|
||||
; CHECK-LABEL: sub_med:
|
||||
define i32 @sub_med_i32(i32 %val32) {
|
||||
; CHECK-LABEL: sub_med_i32:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: adrp x8, :got:var_i32
|
||||
; CHECK-NEXT: adrp x9, :got:var_i64
|
||||
; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32]
|
||||
; CHECK-NEXT: ldr x9, [x9, :got_lo12:var_i64]
|
||||
; CHECK-NEXT: ldr w10, [x8]
|
||||
; CHECK-NEXT: ldr x11, [x9]
|
||||
; CHECK-NEXT: sub w10, w10, #3567, lsl #12 // =14610432
|
||||
; CHECK-NEXT: sub x11, x11, #4095, lsl #12 // =16773120
|
||||
; CHECK-NEXT: str w10, [x8]
|
||||
; CHECK-NEXT: str x11, [x9]
|
||||
; CHECK-NEXT: sub w0, w0, #3567, lsl #12 // =14610432
|
||||
; CHECK-NEXT: ret
|
||||
|
||||
%val32 = load i32, ptr @var_i32
|
||||
%newval32 = sub i32 %val32, 14610432 ; =0xdef000
|
||||
store i32 %newval32, ptr @var_i32
|
||||
ret i32 %newval32
|
||||
}
|
||||
|
||||
%val64 = load i64, ptr @var_i64
|
||||
define i64 @sub_med_i64(i64 %val64) {
|
||||
; CHECK-LABEL: sub_med_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub x0, x0, #4095, lsl #12 // =16773120
|
||||
; CHECK-NEXT: ret
|
||||
%newval64 = sub i64 %val64, 16773120 ; =0xfff000
|
||||
store i64 %newval64, ptr @var_i64
|
||||
|
||||
ret void
|
||||
ret i64 %newval64
|
||||
}
|
||||
|
||||
define i64 @add_two_parts_imm_i64(i64 %a) {
|
||||
@ -261,10 +210,10 @@ define void @add_in_loop(i32 %0) {
|
||||
; CHECK-NEXT: .cfi_offset w30, -16
|
||||
; CHECK-NEXT: mov w19, #43690 // =0xaaaa
|
||||
; CHECK-NEXT: movk w19, #170, lsl #16
|
||||
; CHECK-NEXT: .LBB15_1: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: .LBB19_1: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: add w0, w0, w19
|
||||
; CHECK-NEXT: bl foox
|
||||
; CHECK-NEXT: b .LBB15_1
|
||||
; CHECK-NEXT: b .LBB19_1
|
||||
br label %2
|
||||
2:
|
||||
%3 = phi i32 [ %0, %1 ], [ %5, %2 ]
|
||||
@ -273,75 +222,103 @@ define void @add_in_loop(i32 %0) {
|
||||
br label %2
|
||||
}
|
||||
|
||||
define void @testing() {
|
||||
; CHECK-LABEL: testing:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: adrp x8, :got:var_i32
|
||||
; CHECK-NEXT: ldr x8, [x8, :got_lo12:var_i32]
|
||||
; CHECK-NEXT: ldr w9, [x8]
|
||||
; CHECK-NEXT: cmp w9, #4095
|
||||
; CHECK-NEXT: b.ne .LBB16_6
|
||||
; CHECK-NEXT: // %bb.1: // %test2
|
||||
; CHECK-NEXT: adrp x10, :got:var2_i32
|
||||
; CHECK-NEXT: add w11, w9, #1
|
||||
; CHECK-NEXT: ldr x10, [x10, :got_lo12:var2_i32]
|
||||
; CHECK-NEXT: str w11, [x8]
|
||||
; CHECK-NEXT: ldr w10, [x10]
|
||||
; CHECK-NEXT: cmp w10, #3567, lsl #12 // =14610432
|
||||
; CHECK-NEXT: b.lo .LBB16_6
|
||||
; CHECK-NEXT: // %bb.2: // %test3
|
||||
; CHECK-NEXT: add w11, w9, #2
|
||||
; CHECK-NEXT: cmp w9, #123
|
||||
; CHECK-NEXT: str w11, [x8]
|
||||
; CHECK-NEXT: b.lt .LBB16_6
|
||||
; CHECK-NEXT: // %bb.3: // %test4
|
||||
; CHECK-NEXT: add w11, w9, #3
|
||||
; CHECK-NEXT: cmp w10, #321
|
||||
; CHECK-NEXT: str w11, [x8]
|
||||
; CHECK-NEXT: b.gt .LBB16_6
|
||||
; CHECK-NEXT: // %bb.4: // %test5
|
||||
; CHECK-NEXT: add w11, w9, #4
|
||||
; CHECK-NEXT: cmn w10, #443
|
||||
; CHECK-NEXT: str w11, [x8]
|
||||
; CHECK-NEXT: b.ge .LBB16_6
|
||||
; CHECK-NEXT: // %bb.5: // %test6
|
||||
; CHECK-NEXT: add w9, w9, #5
|
||||
; CHECK-NEXT: str w9, [x8]
|
||||
; CHECK-NEXT: .LBB16_6: // %common.ret
|
||||
; CHECK-NEXT: ret
|
||||
%val = load i32, ptr @var_i32
|
||||
%val2 = load i32, ptr @var2_i32
|
||||
define void @testing(ptr %var_i32, ptr %var2_i32) {
|
||||
; CHECK-SD-LABEL: testing:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: ldr w8, [x0]
|
||||
; CHECK-SD-NEXT: cmp w8, #4095
|
||||
; CHECK-SD-NEXT: b.ne .LBB20_6
|
||||
; CHECK-SD-NEXT: // %bb.1: // %test2
|
||||
; CHECK-SD-NEXT: ldr w9, [x1]
|
||||
; CHECK-SD-NEXT: add w10, w8, #1
|
||||
; CHECK-SD-NEXT: str w10, [x0]
|
||||
; CHECK-SD-NEXT: cmp w9, #3567, lsl #12 // =14610432
|
||||
; CHECK-SD-NEXT: b.lo .LBB20_6
|
||||
; CHECK-SD-NEXT: // %bb.2: // %test3
|
||||
; CHECK-SD-NEXT: add w10, w8, #2
|
||||
; CHECK-SD-NEXT: cmp w8, #123
|
||||
; CHECK-SD-NEXT: str w10, [x0]
|
||||
; CHECK-SD-NEXT: b.lt .LBB20_6
|
||||
; CHECK-SD-NEXT: // %bb.3: // %test4
|
||||
; CHECK-SD-NEXT: add w10, w8, #3
|
||||
; CHECK-SD-NEXT: cmp w9, #321
|
||||
; CHECK-SD-NEXT: str w10, [x0]
|
||||
; CHECK-SD-NEXT: b.gt .LBB20_6
|
||||
; CHECK-SD-NEXT: // %bb.4: // %test5
|
||||
; CHECK-SD-NEXT: add w10, w8, #4
|
||||
; CHECK-SD-NEXT: cmn w9, #443
|
||||
; CHECK-SD-NEXT: str w10, [x0]
|
||||
; CHECK-SD-NEXT: b.ge .LBB20_6
|
||||
; CHECK-SD-NEXT: // %bb.5: // %test6
|
||||
; CHECK-SD-NEXT: add w8, w8, #5
|
||||
; CHECK-SD-NEXT: str w8, [x0]
|
||||
; CHECK-SD-NEXT: .LBB20_6: // %common.ret
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: testing:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: ldr w8, [x0]
|
||||
; CHECK-GI-NEXT: cmp w8, #4095
|
||||
; CHECK-GI-NEXT: b.ne .LBB20_6
|
||||
; CHECK-GI-NEXT: // %bb.1: // %test2
|
||||
; CHECK-GI-NEXT: ldr w9, [x1]
|
||||
; CHECK-GI-NEXT: add w10, w8, #1
|
||||
; CHECK-GI-NEXT: str w10, [x0]
|
||||
; CHECK-GI-NEXT: cmp w9, #3567, lsl #12 // =14610432
|
||||
; CHECK-GI-NEXT: b.lo .LBB20_6
|
||||
; CHECK-GI-NEXT: // %bb.2: // %test3
|
||||
; CHECK-GI-NEXT: add w10, w8, #2
|
||||
; CHECK-GI-NEXT: cmp w8, #123
|
||||
; CHECK-GI-NEXT: str w10, [x0]
|
||||
; CHECK-GI-NEXT: b.lt .LBB20_6
|
||||
; CHECK-GI-NEXT: // %bb.3: // %test4
|
||||
; CHECK-GI-NEXT: add w10, w8, #3
|
||||
; CHECK-GI-NEXT: cmp w9, #321
|
||||
; CHECK-GI-NEXT: str w10, [x0]
|
||||
; CHECK-GI-NEXT: b.gt .LBB20_6
|
||||
; CHECK-GI-NEXT: // %bb.4: // %test5
|
||||
; CHECK-GI-NEXT: add w10, w8, #4
|
||||
; CHECK-GI-NEXT: cmn w9, #444
|
||||
; CHECK-GI-NEXT: str w10, [x0]
|
||||
; CHECK-GI-NEXT: b.gt .LBB20_6
|
||||
; CHECK-GI-NEXT: // %bb.5: // %test6
|
||||
; CHECK-GI-NEXT: add w8, w8, #5
|
||||
; CHECK-GI-NEXT: str w8, [x0]
|
||||
; CHECK-GI-NEXT: .LBB20_6: // %common.ret
|
||||
; CHECK-GI-NEXT: ret
|
||||
%val = load i32, ptr %var_i32
|
||||
%val2 = load i32, ptr %var2_i32
|
||||
|
||||
%cmp_pos_small = icmp ne i32 %val, 4095
|
||||
br i1 %cmp_pos_small, label %ret, label %test2
|
||||
|
||||
test2:
|
||||
%newval2 = add i32 %val, 1
|
||||
store i32 %newval2, ptr @var_i32
|
||||
store i32 %newval2, ptr %var_i32
|
||||
%cmp_pos_big = icmp ult i32 %val2, 14610432
|
||||
br i1 %cmp_pos_big, label %ret, label %test3
|
||||
|
||||
test3:
|
||||
%newval3 = add i32 %val, 2
|
||||
store i32 %newval3, ptr @var_i32
|
||||
store i32 %newval3, ptr %var_i32
|
||||
%cmp_pos_slt = icmp slt i32 %val, 123
|
||||
br i1 %cmp_pos_slt, label %ret, label %test4
|
||||
|
||||
test4:
|
||||
%newval4 = add i32 %val, 3
|
||||
store i32 %newval4, ptr @var_i32
|
||||
store i32 %newval4, ptr %var_i32
|
||||
%cmp_pos_sgt = icmp sgt i32 %val2, 321
|
||||
br i1 %cmp_pos_sgt, label %ret, label %test5
|
||||
|
||||
test5:
|
||||
%newval5 = add i32 %val, 4
|
||||
store i32 %newval5, ptr @var_i32
|
||||
store i32 %newval5, ptr %var_i32
|
||||
%cmp_neg_uge = icmp sgt i32 %val2, -444
|
||||
br i1 %cmp_neg_uge, label %ret, label %test6
|
||||
|
||||
test6:
|
||||
%newval6 = add i32 %val, 5
|
||||
store i32 %newval6, ptr @var_i32
|
||||
store i32 %newval6, ptr %var_i32
|
||||
ret void
|
||||
|
||||
ret:
|
||||
@ -371,15 +348,26 @@ define i1 @sadd_add(i32 %a, i32 %b, ptr %p) {
|
||||
declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
|
||||
|
||||
define i1 @uadd_add(i8 %a, i8 %b, ptr %p) {
|
||||
; CHECK-LABEL: uadd_add:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: mov w8, #255 // =0xff
|
||||
; CHECK-NEXT: bic w8, w8, w0
|
||||
; CHECK-NEXT: add w8, w8, w1, uxtb
|
||||
; CHECK-NEXT: lsr w0, w8, #8
|
||||
; CHECK-NEXT: add w8, w8, #1
|
||||
; CHECK-NEXT: strb w8, [x2]
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: uadd_add:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: mov w8, #255 // =0xff
|
||||
; CHECK-SD-NEXT: bic w8, w8, w0
|
||||
; CHECK-SD-NEXT: add w8, w8, w1, uxtb
|
||||
; CHECK-SD-NEXT: lsr w0, w8, #8
|
||||
; CHECK-SD-NEXT: add w8, w8, #1
|
||||
; CHECK-SD-NEXT: strb w8, [x2]
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: uadd_add:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mvn w8, w0
|
||||
; CHECK-GI-NEXT: and w9, w1, #0xff
|
||||
; CHECK-GI-NEXT: add w8, w9, w8, uxtb
|
||||
; CHECK-GI-NEXT: cmp w8, w8, uxtb
|
||||
; CHECK-GI-NEXT: add w8, w8, #1
|
||||
; CHECK-GI-NEXT: cset w0, ne
|
||||
; CHECK-GI-NEXT: strb w8, [x2]
|
||||
; CHECK-GI-NEXT: ret
|
||||
%nota = xor i8 %a, -1
|
||||
%a0 = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 %nota, i8 %b)
|
||||
%e0 = extractvalue {i8, i1} %a0, 0
|
||||
@ -521,29 +509,48 @@ define i1 @reject_non_eqne_csinc(i32 %0) {
|
||||
}
|
||||
|
||||
define i32 @accept_csel(i32 %0) {
|
||||
; CHECK-LABEL: accept_csel:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w9, w0, #273, lsl #12 // =1118208
|
||||
; CHECK-NEXT: mov w8, #17 // =0x11
|
||||
; CHECK-NEXT: cmp w9, #273
|
||||
; CHECK-NEXT: mov w9, #11 // =0xb
|
||||
; CHECK-NEXT: csel w0, w9, w8, eq
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: accept_csel:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w9, w0, #273, lsl #12 // =1118208
|
||||
; CHECK-SD-NEXT: mov w8, #17 // =0x11
|
||||
; CHECK-SD-NEXT: cmp w9, #273
|
||||
; CHECK-SD-NEXT: mov w9, #11 // =0xb
|
||||
; CHECK-SD-NEXT: csel w0, w9, w8, eq
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: accept_csel:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: sub w8, w0, #273, lsl #12 // =1118208
|
||||
; CHECK-GI-NEXT: mov w9, #17 // =0x11
|
||||
; CHECK-GI-NEXT: mov w10, #11 // =0xb
|
||||
; CHECK-GI-NEXT: cmp w8, #273
|
||||
; CHECK-GI-NEXT: csel w0, w10, w9, eq
|
||||
; CHECK-GI-NEXT: ret
|
||||
%2 = icmp eq i32 %0, 1118481
|
||||
%3 = select i1 %2, i32 11, i32 17
|
||||
ret i32 %3
|
||||
}
|
||||
|
||||
define i32 @reject_non_eqne_csel(i32 %0) {
|
||||
; CHECK-LABEL: reject_non_eqne_csel:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: mov w8, #4369 // =0x1111
|
||||
; CHECK-NEXT: mov w9, #11 // =0xb
|
||||
; CHECK-NEXT: movk w8, #17, lsl #16
|
||||
; CHECK-NEXT: cmp w0, w8
|
||||
; CHECK-NEXT: mov w8, #17 // =0x11
|
||||
; CHECK-NEXT: csel w0, w9, w8, lo
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: reject_non_eqne_csel:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: mov w8, #4369 // =0x1111
|
||||
; CHECK-SD-NEXT: mov w9, #11 // =0xb
|
||||
; CHECK-SD-NEXT: movk w8, #17, lsl #16
|
||||
; CHECK-SD-NEXT: cmp w0, w8
|
||||
; CHECK-SD-NEXT: mov w8, #17 // =0x11
|
||||
; CHECK-SD-NEXT: csel w0, w9, w8, lo
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: reject_non_eqne_csel:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mov w8, #4369 // =0x1111
|
||||
; CHECK-GI-NEXT: mov w9, #17 // =0x11
|
||||
; CHECK-GI-NEXT: mov w10, #11 // =0xb
|
||||
; CHECK-GI-NEXT: movk w8, #17, lsl #16
|
||||
; CHECK-GI-NEXT: cmp w0, w8
|
||||
; CHECK-GI-NEXT: csel w0, w10, w9, lo
|
||||
; CHECK-GI-NEXT: ret
|
||||
%2 = icmp ult i32 %0, 1118481
|
||||
%3 = select i1 %2, i32 11, i32 17
|
||||
ret i32 %3
|
||||
@ -556,10 +563,10 @@ define void @accept_branch(i32 %0) {
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w0, #291, lsl #12 // =1191936
|
||||
; CHECK-NEXT: cmp w8, #1110
|
||||
; CHECK-NEXT: b.eq .LBB32_2
|
||||
; CHECK-NEXT: b.eq .LBB36_2
|
||||
; CHECK-NEXT: // %bb.1:
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-NEXT: .LBB32_2:
|
||||
; CHECK-NEXT: .LBB36_2:
|
||||
; CHECK-NEXT: b fooy
|
||||
%2 = icmp ne i32 %0, 1193046
|
||||
br i1 %2, label %4, label %3
|
||||
@ -576,10 +583,10 @@ define void @reject_non_eqne_branch(i32 %0) {
|
||||
; CHECK-NEXT: mov w8, #13398 // =0x3456
|
||||
; CHECK-NEXT: movk w8, #18, lsl #16
|
||||
; CHECK-NEXT: cmp w0, w8
|
||||
; CHECK-NEXT: b.le .LBB33_2
|
||||
; CHECK-NEXT: b.le .LBB37_2
|
||||
; CHECK-NEXT: // %bb.1:
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-NEXT: .LBB33_2:
|
||||
; CHECK-NEXT: .LBB37_2:
|
||||
; CHECK-NEXT: b fooy
|
||||
%2 = icmp sgt i32 %0, 1193046
|
||||
br i1 %2, label %4, label %3
|
||||
@ -591,25 +598,45 @@ define void @reject_non_eqne_branch(i32 %0) {
|
||||
}
|
||||
|
||||
define i32 @reject_multiple_usages(i32 %0) {
|
||||
; CHECK-LABEL: reject_multiple_usages:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: mov w8, #4369 // =0x1111
|
||||
; CHECK-NEXT: mov w9, #3 // =0x3
|
||||
; CHECK-NEXT: mov w10, #17 // =0x11
|
||||
; CHECK-NEXT: movk w8, #17, lsl #16
|
||||
; CHECK-NEXT: mov w11, #12 // =0xc
|
||||
; CHECK-NEXT: cmp w0, w8
|
||||
; CHECK-NEXT: mov w8, #9 // =0x9
|
||||
; CHECK-NEXT: csel w8, w8, w9, eq
|
||||
; CHECK-NEXT: csel w9, w11, w10, hi
|
||||
; CHECK-NEXT: mov w10, #53312 // =0xd040
|
||||
; CHECK-NEXT: movk w10, #2, lsl #16
|
||||
; CHECK-NEXT: add w8, w8, w9
|
||||
; CHECK-NEXT: mov w9, #26304 // =0x66c0
|
||||
; CHECK-NEXT: cmp w0, w10
|
||||
; CHECK-NEXT: movk w9, #1433, lsl #16
|
||||
; CHECK-NEXT: csel w0, w8, w9, hi
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: reject_multiple_usages:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: mov w8, #4369 // =0x1111
|
||||
; CHECK-SD-NEXT: mov w9, #3 // =0x3
|
||||
; CHECK-SD-NEXT: mov w10, #17 // =0x11
|
||||
; CHECK-SD-NEXT: movk w8, #17, lsl #16
|
||||
; CHECK-SD-NEXT: mov w11, #12 // =0xc
|
||||
; CHECK-SD-NEXT: cmp w0, w8
|
||||
; CHECK-SD-NEXT: mov w8, #9 // =0x9
|
||||
; CHECK-SD-NEXT: csel w8, w8, w9, eq
|
||||
; CHECK-SD-NEXT: csel w9, w11, w10, hi
|
||||
; CHECK-SD-NEXT: mov w10, #53312 // =0xd040
|
||||
; CHECK-SD-NEXT: movk w10, #2, lsl #16
|
||||
; CHECK-SD-NEXT: add w8, w8, w9
|
||||
; CHECK-SD-NEXT: mov w9, #26304 // =0x66c0
|
||||
; CHECK-SD-NEXT: cmp w0, w10
|
||||
; CHECK-SD-NEXT: movk w9, #1433, lsl #16
|
||||
; CHECK-SD-NEXT: csel w0, w8, w9, hi
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: reject_multiple_usages:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mov w8, #4369 // =0x1111
|
||||
; CHECK-GI-NEXT: mov w9, #3 // =0x3
|
||||
; CHECK-GI-NEXT: mov w10, #9 // =0x9
|
||||
; CHECK-GI-NEXT: movk w8, #17, lsl #16
|
||||
; CHECK-GI-NEXT: mov w11, #12 // =0xc
|
||||
; CHECK-GI-NEXT: cmp w0, w8
|
||||
; CHECK-GI-NEXT: mov w8, #17 // =0x11
|
||||
; CHECK-GI-NEXT: csel w9, w10, w9, eq
|
||||
; CHECK-GI-NEXT: csel w8, w11, w8, hi
|
||||
; CHECK-GI-NEXT: mov w10, #53312 // =0xd040
|
||||
; CHECK-GI-NEXT: movk w10, #2, lsl #16
|
||||
; CHECK-GI-NEXT: add w8, w9, w8
|
||||
; CHECK-GI-NEXT: mov w9, #26304 // =0x66c0
|
||||
; CHECK-GI-NEXT: movk w9, #1433, lsl #16
|
||||
; CHECK-GI-NEXT: cmp w0, w10
|
||||
; CHECK-GI-NEXT: csel w0, w8, w9, hi
|
||||
; CHECK-GI-NEXT: ret
|
||||
%2 = icmp eq i32 %0, 1118481
|
||||
%3 = icmp ugt i32 %0, 1118481
|
||||
%4 = select i1 %2, i32 9, i32 3
|
||||
@ -629,12 +656,12 @@ define dso_local i32 @neigh_periodic_work_tbl_1() {
|
||||
; CHECK-NEXT: add x8, x8, :lo12:neigh_periodic_work_tbl_1
|
||||
; CHECK-NEXT: add x8, x8, #18, lsl #12 // =73728
|
||||
; CHECK-NEXT: cmn x8, #1272
|
||||
; CHECK-NEXT: b.mi .LBB35_2
|
||||
; CHECK-NEXT: b.mi .LBB39_2
|
||||
; CHECK-NEXT: // %bb.1: // %if.end
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-NEXT: .LBB35_2: // %for.cond
|
||||
; CHECK-NEXT: .LBB39_2: // %for.cond
|
||||
; CHECK-NEXT: // =>This Inner Loop Header: Depth=1
|
||||
; CHECK-NEXT: b .LBB35_2
|
||||
; CHECK-NEXT: b .LBB39_2
|
||||
entry:
|
||||
%cmp = icmp slt i64 add (i64 ptrtoint (ptr @neigh_periodic_work_tbl_1 to i64), i64 75000), 0
|
||||
br i1 %cmp, label %for.cond, label %if.end
|
||||
@ -654,15 +681,15 @@ define dso_local i32 @_extract_crng_crng() {
|
||||
; CHECK: // %bb.0: // %entry
|
||||
; CHECK-NEXT: adrp x8, _extract_crng_crng
|
||||
; CHECK-NEXT: add x8, x8, :lo12:_extract_crng_crng
|
||||
; CHECK-NEXT: tbnz x8, #63, .LBB36_2
|
||||
; CHECK-NEXT: tbnz x8, #63, .LBB40_2
|
||||
; CHECK-NEXT: // %bb.1: // %lor.lhs.false
|
||||
; CHECK-NEXT: adrp x9, jiffies
|
||||
; CHECK-NEXT: ldrsw x9, [x9, :lo12:jiffies]
|
||||
; CHECK-NEXT: sub x8, x8, x9
|
||||
; CHECK-NEXT: add x8, x8, #18, lsl #12 // =73728
|
||||
; CHECK-NEXT: cmn x8, #1272
|
||||
; CHECK-NEXT: b.pl .LBB36_3
|
||||
; CHECK-NEXT: .LBB36_2: // %if.then
|
||||
; CHECK-NEXT: b.pl .LBB40_3
|
||||
; CHECK-NEXT: .LBB40_2: // %if.then
|
||||
; CHECK-NEXT: adrp x8, primary_crng
|
||||
; CHECK-NEXT: ldr w8, [x8, :lo12:primary_crng]
|
||||
; CHECK-NEXT: cmp w8, #0
|
||||
@ -670,7 +697,7 @@ define dso_local i32 @_extract_crng_crng() {
|
||||
; CHECK-NEXT: add x8, x8, :lo12:input_pool
|
||||
; CHECK-NEXT: csel x0, xzr, x8, eq
|
||||
; CHECK-NEXT: b crng_reseed
|
||||
; CHECK-NEXT: .LBB36_3: // %if.end
|
||||
; CHECK-NEXT: .LBB40_3: // %if.end
|
||||
; CHECK-NEXT: ret
|
||||
entry:
|
||||
%cmp2 = icmp slt ptr @_extract_crng_crng, null
|
||||
@ -694,11 +721,18 @@ if.end: ; preds = %if.then, %lor.lhs.f
|
||||
|
||||
; ((X << C) - Y) + Z --> (Z - Y) + (X << C)
|
||||
define i32 @commute_subop0(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w2, w1
|
||||
; CHECK-NEXT: add w0, w8, w0, lsl #3
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w2, w1
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, lsl #3
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: lsl w8, w0, #3
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w0, w8, w2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%shl = shl i32 %x, 3
|
||||
%sub = sub i32 %shl, %y
|
||||
%add = add i32 %sub, %z
|
||||
@ -707,11 +741,18 @@ define i32 @commute_subop0(i32 %x, i32 %y, i32 %z) {
|
||||
|
||||
; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
|
||||
define i32 @commute_subop0_lshr(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0_lshr:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w2, w1
|
||||
; CHECK-NEXT: add w0, w8, w0, lsr #3
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_lshr:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w2, w1
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, lsr #3
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_lshr:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: lsr w8, w0, #3
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w0, w8, w2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%lshr = lshr i32 %x, 3
|
||||
%sub = sub i32 %lshr, %y
|
||||
%add = add i32 %sub, %z
|
||||
@ -720,11 +761,18 @@ define i32 @commute_subop0_lshr(i32 %x, i32 %y, i32 %z) {
|
||||
|
||||
; ((X >> C) - Y) + Z --> (Z - Y) + (X >> C)
|
||||
define i32 @commute_subop0_ashr(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0_ashr:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w2, w1
|
||||
; CHECK-NEXT: add w0, w8, w0, asr #3
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_ashr:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w2, w1
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, asr #3
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_ashr:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: asr w8, w0, #3
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w0, w8, w2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%ashr = ashr i32 %x, 3
|
||||
%sub = sub i32 %ashr, %y
|
||||
%add = add i32 %sub, %z
|
||||
@ -733,11 +781,19 @@ define i32 @commute_subop0_ashr(i32 %x, i32 %y, i32 %z) {
|
||||
|
||||
; ((sext X) - Y) + Z --> (Z - Y) + (sext X)
|
||||
define i64 @commute_subop0_sext(i32 %x, i64 %y, i64 %z) {
|
||||
; CHECK-LABEL: commute_subop0_sext:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub x8, x2, x1
|
||||
; CHECK-NEXT: add x0, x8, w0, sxtw
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_sext:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub x8, x2, x1
|
||||
; CHECK-SD-NEXT: add x0, x8, w0, sxtw
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_sext:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: // kill: def $w0 killed $w0 def $x0
|
||||
; CHECK-GI-NEXT: sxtw x8, w0
|
||||
; CHECK-GI-NEXT: sub x8, x8, x1
|
||||
; CHECK-GI-NEXT: add x0, x8, x2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%sext = sext i32 %x to i64
|
||||
%sub = sub i64 %sext, %y
|
||||
%add = add i64 %sub, %z
|
||||
@ -746,11 +802,18 @@ define i64 @commute_subop0_sext(i32 %x, i64 %y, i64 %z) {
|
||||
|
||||
; ((sext_inreg X) - Y) + Z --> (Z - Y) + (sext_inreg X)
|
||||
define i64 @commute_subop0_sext_inreg(i64 %x, i64 %y, i64 %z) {
|
||||
; CHECK-LABEL: commute_subop0_sext_inreg:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub x8, x2, x1
|
||||
; CHECK-NEXT: add x0, x8, w0, sxth
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_sext_inreg:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub x8, x2, x1
|
||||
; CHECK-SD-NEXT: add x0, x8, w0, sxth
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_sext_inreg:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: sxth x8, w0
|
||||
; CHECK-GI-NEXT: sub x8, x8, x1
|
||||
; CHECK-GI-NEXT: add x0, x8, x2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%shl = shl i64 %x, 48
|
||||
%ashr = ashr i64 %shl, 48
|
||||
%sub = sub i64 %ashr, %y
|
||||
@ -760,11 +823,18 @@ define i64 @commute_subop0_sext_inreg(i64 %x, i64 %y, i64 %z) {
|
||||
|
||||
; ((zext X) - Y) + Z --> (Z - Y) + (zext X)
|
||||
define i32 @commute_subop0_zext(i16 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0_zext:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w2, w1
|
||||
; CHECK-NEXT: add w0, w8, w0, uxth
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_zext:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w2, w1
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, uxth
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_zext:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w0, #0xffff
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w0, w8, w2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%zext = zext i16 %x to i32
|
||||
%sub = sub i32 %zext, %y
|
||||
%add = add i32 %sub, %z
|
||||
@ -774,14 +844,25 @@ define i32 @commute_subop0_zext(i16 %x, i32 %y, i32 %z) {
|
||||
|
||||
; ((anyext X) - Y) + Z --> (Z - Y) + (anyext X)
|
||||
define i8 @commute_subop0_anyext(i16 %a, i16 %b, i32 %c) {
|
||||
; CHECK-LABEL: commute_subop0_anyext:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: mov w8, #111 // =0x6f
|
||||
; CHECK-NEXT: sub w9, w2, w1
|
||||
; CHECK-NEXT: madd w8, w0, w8, w9
|
||||
; CHECK-NEXT: lsl w8, w8, #3
|
||||
; CHECK-NEXT: sub w0, w8, #1776
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_anyext:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: mov w8, #111 // =0x6f
|
||||
; CHECK-SD-NEXT: sub w9, w2, w1
|
||||
; CHECK-SD-NEXT: madd w8, w0, w8, w9
|
||||
; CHECK-SD-NEXT: lsl w8, w8, #3
|
||||
; CHECK-SD-NEXT: sub w0, w8, #1776
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_anyext:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mov w8, #111 // =0x6f
|
||||
; CHECK-GI-NEXT: add w9, w1, #222
|
||||
; CHECK-GI-NEXT: mul w8, w0, w8
|
||||
; CHECK-GI-NEXT: and w8, w8, #0xffff
|
||||
; CHECK-GI-NEXT: sub w8, w8, w9, uxth
|
||||
; CHECK-GI-NEXT: add w8, w8, w2
|
||||
; CHECK-GI-NEXT: lsl w0, w8, #3
|
||||
; CHECK-GI-NEXT: ret
|
||||
%aa = mul i16 %a, 111
|
||||
%bb = add i16 %b, 222
|
||||
%a_32 = zext i16 %aa to i32
|
||||
@ -795,11 +876,18 @@ define i8 @commute_subop0_anyext(i16 %a, i16 %b, i32 %c) {
|
||||
|
||||
; ((X and C) - Y) + Z --> (Z - Y) + (X and C)
|
||||
define i32 @commute_subop0_and(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0_and:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w2, w1
|
||||
; CHECK-NEXT: add w0, w8, w0, uxtb
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_and:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w2, w1
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, uxtb
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_and:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w0, #0xff
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w0, w8, w2
|
||||
; CHECK-GI-NEXT: ret
|
||||
%and = and i32 %x, 255
|
||||
%sub = sub i32 %and, %y
|
||||
%add = add i32 %sub, %z
|
||||
@ -808,11 +896,18 @@ define i32 @commute_subop0_and(i32 %x, i32 %y, i32 %z) {
|
||||
|
||||
; Z + ((X << C) - Y) --> (Z - Y) + (X << C)
|
||||
define i32 @commute_subop0_cadd(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0_cadd:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w2, w1
|
||||
; CHECK-NEXT: add w0, w8, w0, lsl #3
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_cadd:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w2, w1
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, lsl #3
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_cadd:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: lsl w8, w0, #3
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w0, w2, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%shl = shl i32 %x, 3
|
||||
%sub = sub i32 %shl, %y
|
||||
%add = add i32 %z, %sub
|
||||
@ -821,11 +916,18 @@ define i32 @commute_subop0_cadd(i32 %x, i32 %y, i32 %z) {
|
||||
|
||||
; Y + ((X << C) - X) --> (Y - X) + (X << C)
|
||||
define i32 @commute_subop0_mul(i32 %x, i32 %y) {
|
||||
; CHECK-LABEL: commute_subop0_mul:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sub w8, w1, w0
|
||||
; CHECK-NEXT: add w0, w8, w0, lsl #3
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_mul:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sub w8, w1, w0
|
||||
; CHECK-SD-NEXT: add w0, w8, w0, lsl #3
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_mul:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: lsl w8, w0, #3
|
||||
; CHECK-GI-NEXT: sub w8, w8, w0
|
||||
; CHECK-GI-NEXT: add w0, w8, w1
|
||||
; CHECK-GI-NEXT: ret
|
||||
%mul = mul i32 %x, 7
|
||||
%add = add i32 %mul, %y
|
||||
ret i32 %add
|
||||
@ -863,13 +965,22 @@ define i32 @commute_subop0_zshiftc_oneuse(i32 %x, i32 %y, i32 %z) {
|
||||
}
|
||||
|
||||
define i32 @commute_subop0_zshiftc(i32 %x, i32 %y, i32 %z) {
|
||||
; CHECK-LABEL: commute_subop0_zshiftc:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: lsl w8, w2, #2
|
||||
; CHECK-NEXT: sub w9, w8, w1
|
||||
; CHECK-NEXT: add w9, w9, w0, lsl #3
|
||||
; CHECK-NEXT: eor w0, w8, w9
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: commute_subop0_zshiftc:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: lsl w8, w2, #2
|
||||
; CHECK-SD-NEXT: sub w9, w8, w1
|
||||
; CHECK-SD-NEXT: add w9, w9, w0, lsl #3
|
||||
; CHECK-SD-NEXT: eor w0, w8, w9
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: commute_subop0_zshiftc:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: lsl w8, w0, #3
|
||||
; CHECK-GI-NEXT: lsl w9, w2, #2
|
||||
; CHECK-GI-NEXT: sub w8, w8, w1
|
||||
; CHECK-GI-NEXT: add w8, w8, w9
|
||||
; CHECK-GI-NEXT: eor w0, w9, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%xshl = shl i32 %x, 3
|
||||
%sub = sub i32 %xshl, %y
|
||||
%zshl = shl i32 %z, 2
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,6 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -verify-machineinstrs < %s -mtriple=aarch64-none-linux-gnu | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-none-elf < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-elf -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
@var1_32 = global i32 0
|
||||
@var2_32 = global i32 0
|
||||
@ -243,26 +244,48 @@ define void @logical_64bit() minsize {
|
||||
}
|
||||
|
||||
define void @flag_setting() {
|
||||
; CHECK-LABEL: flag_setting:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: adrp x8, :got:var1_64
|
||||
; CHECK-NEXT: adrp x10, :got:var2_64
|
||||
; CHECK-NEXT: ldr x8, [x8, :got_lo12:var1_64]
|
||||
; CHECK-NEXT: ldr x10, [x10, :got_lo12:var2_64]
|
||||
; CHECK-NEXT: ldr x9, [x8]
|
||||
; CHECK-NEXT: ldr x10, [x10]
|
||||
; CHECK-NEXT: tst x9, x10
|
||||
; CHECK-NEXT: b.gt .LBB2_4
|
||||
; CHECK-NEXT: // %bb.1: // %test2
|
||||
; CHECK-NEXT: tst x9, x10, lsl #63
|
||||
; CHECK-NEXT: b.lt .LBB2_4
|
||||
; CHECK-NEXT: // %bb.2: // %test3
|
||||
; CHECK-NEXT: tst x9, x10, asr #12
|
||||
; CHECK-NEXT: b.gt .LBB2_4
|
||||
; CHECK-NEXT: // %bb.3: // %other_exit
|
||||
; CHECK-NEXT: str x9, [x8]
|
||||
; CHECK-NEXT: .LBB2_4: // %common.ret
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: flag_setting:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: adrp x8, :got:var1_64
|
||||
; CHECK-SD-NEXT: adrp x10, :got:var2_64
|
||||
; CHECK-SD-NEXT: ldr x8, [x8, :got_lo12:var1_64]
|
||||
; CHECK-SD-NEXT: ldr x10, [x10, :got_lo12:var2_64]
|
||||
; CHECK-SD-NEXT: ldr x9, [x8]
|
||||
; CHECK-SD-NEXT: ldr x10, [x10]
|
||||
; CHECK-SD-NEXT: tst x9, x10
|
||||
; CHECK-SD-NEXT: b.gt .LBB2_4
|
||||
; CHECK-SD-NEXT: // %bb.1: // %test2
|
||||
; CHECK-SD-NEXT: tst x9, x10, lsl #63
|
||||
; CHECK-SD-NEXT: b.lt .LBB2_4
|
||||
; CHECK-SD-NEXT: // %bb.2: // %test3
|
||||
; CHECK-SD-NEXT: tst x9, x10, asr #12
|
||||
; CHECK-SD-NEXT: b.gt .LBB2_4
|
||||
; CHECK-SD-NEXT: // %bb.3: // %other_exit
|
||||
; CHECK-SD-NEXT: str x9, [x8]
|
||||
; CHECK-SD-NEXT: .LBB2_4: // %common.ret
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: flag_setting:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: adrp x8, :got:var1_64
|
||||
; CHECK-GI-NEXT: adrp x10, :got:var2_64
|
||||
; CHECK-GI-NEXT: ldr x8, [x8, :got_lo12:var1_64]
|
||||
; CHECK-GI-NEXT: ldr x10, [x10, :got_lo12:var2_64]
|
||||
; CHECK-GI-NEXT: ldr x9, [x8]
|
||||
; CHECK-GI-NEXT: ldr x10, [x10]
|
||||
; CHECK-GI-NEXT: tst x9, x10
|
||||
; CHECK-GI-NEXT: b.gt .LBB2_4
|
||||
; CHECK-GI-NEXT: // %bb.1: // %test2
|
||||
; CHECK-GI-NEXT: tst x9, x10, lsl #63
|
||||
; CHECK-GI-NEXT: b.lt .LBB2_4
|
||||
; CHECK-GI-NEXT: // %bb.2: // %test3
|
||||
; CHECK-GI-NEXT: asr x10, x10, #12
|
||||
; CHECK-GI-NEXT: tst x10, x9
|
||||
; CHECK-GI-NEXT: b.gt .LBB2_4
|
||||
; CHECK-GI-NEXT: // %bb.3: // %other_exit
|
||||
; CHECK-GI-NEXT: str x9, [x8]
|
||||
; CHECK-GI-NEXT: .LBB2_4: // %common.ret
|
||||
; CHECK-GI-NEXT: ret
|
||||
%val1 = load i64, ptr @var1_64
|
||||
%val2 = load i64, ptr @var2_64
|
||||
|
||||
|
@ -1,15 +1,22 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -verify-machineinstrs \
|
||||
; RUN: -mtriple=aarch64-unknown-unknown < %s | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-none-elf < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-elf -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
declare i64 @llvm.abs.i64(i64, i1 immarg)
|
||||
|
||||
define i64 @neg_abs64(i64 %x) {
|
||||
; CHECK-LABEL: neg_abs64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: cmp x0, #0
|
||||
; CHECK-NEXT: cneg x0, x0, pl
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_abs64:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: cmp x0, #0
|
||||
; CHECK-SD-NEXT: cneg x0, x0, pl
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_abs64:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: cmp x0, #0
|
||||
; CHECK-GI-NEXT: cneg x8, x0, le
|
||||
; CHECK-GI-NEXT: neg x0, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
|
||||
%neg = sub nsw i64 0, %abs
|
||||
ret i64 %neg
|
||||
@ -18,11 +25,18 @@ define i64 @neg_abs64(i64 %x) {
|
||||
declare i32 @llvm.abs.i32(i32, i1 immarg)
|
||||
|
||||
define i32 @neg_abs32(i32 %x) {
|
||||
; CHECK-LABEL: neg_abs32:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: cmp w0, #0
|
||||
; CHECK-NEXT: cneg w0, w0, pl
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_abs32:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: cmp w0, #0
|
||||
; CHECK-SD-NEXT: cneg w0, w0, pl
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_abs32:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: cmp w0, #0
|
||||
; CHECK-GI-NEXT: cneg w8, w0, le
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
|
||||
%neg = sub nsw i32 0, %abs
|
||||
ret i32 %neg
|
||||
@ -31,12 +45,20 @@ define i32 @neg_abs32(i32 %x) {
|
||||
declare i16 @llvm.abs.i16(i16, i1 immarg)
|
||||
|
||||
define i16 @neg_abs16(i16 %x) {
|
||||
; CHECK-LABEL: neg_abs16:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sbfx w8, w0, #15, #1
|
||||
; CHECK-NEXT: eor w9, w0, w8
|
||||
; CHECK-NEXT: sub w0, w8, w9
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_abs16:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: sbfx w8, w0, #15, #1
|
||||
; CHECK-SD-NEXT: eor w9, w0, w8
|
||||
; CHECK-SD-NEXT: sub w0, w8, w9
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_abs16:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: sxth w8, w0
|
||||
; CHECK-GI-NEXT: cmp w8, #0
|
||||
; CHECK-GI-NEXT: cneg w8, w0, le
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true)
|
||||
%neg = sub nsw i16 0, %abs
|
||||
ret i16 %neg
|
||||
@ -46,14 +68,25 @@ define i16 @neg_abs16(i16 %x) {
|
||||
declare i128 @llvm.abs.i128(i128, i1 immarg)
|
||||
|
||||
define i128 @neg_abs128(i128 %x) {
|
||||
; CHECK-LABEL: neg_abs128:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: asr x8, x1, #63
|
||||
; CHECK-NEXT: eor x9, x0, x8
|
||||
; CHECK-NEXT: eor x10, x1, x8
|
||||
; CHECK-NEXT: subs x0, x8, x9
|
||||
; CHECK-NEXT: sbc x1, x8, x10
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_abs128:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; 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, x8, x9
|
||||
; CHECK-SD-NEXT: sbc x1, x8, x10
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_abs128:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; 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 x9, x9, x8
|
||||
; CHECK-GI-NEXT: eor x8, x10, x8
|
||||
; CHECK-GI-NEXT: negs x0, x9
|
||||
; CHECK-GI-NEXT: ngc x1, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i128 @llvm.abs.i128(i128 %x, i1 true)
|
||||
%neg = sub nsw i128 0, %abs
|
||||
ret i128 %neg
|
||||
@ -62,46 +95,76 @@ define i128 @neg_abs128(i128 %x) {
|
||||
|
||||
|
||||
define i64 @abs64(i64 %x) {
|
||||
; CHECK-LABEL: abs64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: cmp x0, #0
|
||||
; CHECK-NEXT: cneg x0, x0, mi
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: abs64:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: cmp x0, #0
|
||||
; CHECK-SD-NEXT: cneg x0, x0, mi
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: abs64:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: cmp x0, #0
|
||||
; CHECK-GI-NEXT: cneg x0, x0, le
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i64 @llvm.abs.i64(i64 %x, i1 true)
|
||||
ret i64 %abs
|
||||
}
|
||||
|
||||
define i32 @abs32(i32 %x) {
|
||||
; CHECK-LABEL: abs32:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: cmp w0, #0
|
||||
; CHECK-NEXT: cneg w0, w0, mi
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: abs32:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: cmp w0, #0
|
||||
; CHECK-SD-NEXT: cneg w0, w0, mi
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: abs32:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: cmp w0, #0
|
||||
; CHECK-GI-NEXT: cneg w0, w0, le
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i32 @llvm.abs.i32(i32 %x, i1 true)
|
||||
ret i32 %abs
|
||||
}
|
||||
|
||||
define i16 @abs16(i16 %x) {
|
||||
; CHECK-LABEL: abs16:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: sxth w8, w0
|
||||
; CHECK-NEXT: cmp w8, #0
|
||||
; CHECK-NEXT: cneg w0, w8, mi
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: abs16:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; 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: abs16:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: sxth w8, w0
|
||||
; CHECK-GI-NEXT: cmp w8, #0
|
||||
; CHECK-GI-NEXT: cneg w0, w0, le
|
||||
; CHECK-GI-NEXT: ret
|
||||
%abs = tail call i16 @llvm.abs.i16(i16 %x, i1 true)
|
||||
ret i16 %abs
|
||||
}
|
||||
|
||||
define i128 @abs128(i128 %x) {
|
||||
; CHECK-LABEL: abs128:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: asr x8, x1, #63
|
||||
; CHECK-NEXT: eor x9, x0, x8
|
||||
; CHECK-NEXT: eor x10, x1, x8
|
||||
; CHECK-NEXT: subs x0, x9, x8
|
||||
; CHECK-NEXT: sbc x1, x10, x8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: abs128:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; 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: abs128:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; 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
|
||||
%abs = tail call i128 @llvm.abs.i128(i128 %x, i1 true)
|
||||
ret i128 %abs
|
||||
}
|
||||
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; CHECK: {{.*}}
|
||||
|
@ -1,12 +1,22 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple=aarch64-none-elf %s -o - | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-none-elf < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-elf -global-isel < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
define i32 @neg_select_neg(i32 %a, i32 %b, i1 %bb) {
|
||||
; CHECK-LABEL: neg_select_neg:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: tst w2, #0x1
|
||||
; CHECK-NEXT: csel w0, w0, w1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_select_neg:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: tst w2, #0x1
|
||||
; CHECK-SD-NEXT: csel w0, w0, w1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_select_neg:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w2, #0x1
|
||||
; CHECK-GI-NEXT: neg w9, w0
|
||||
; CHECK-GI-NEXT: tst w8, #0x1
|
||||
; CHECK-GI-NEXT: csneg w8, w9, w1, ne
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%nega = sub i32 0, %a
|
||||
%negb = sub i32 0, %b
|
||||
%sel = select i1 %bb, i32 %nega, i32 %negb
|
||||
@ -15,11 +25,20 @@ define i32 @neg_select_neg(i32 %a, i32 %b, i1 %bb) {
|
||||
}
|
||||
|
||||
define i32 @negneg_select_nega(i32 %a, i32 %b, i1 %bb) {
|
||||
; CHECK-LABEL: negneg_select_nega:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: tst w2, #0x1
|
||||
; CHECK-NEXT: csneg w0, w1, w0, eq
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: negneg_select_nega:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: tst w2, #0x1
|
||||
; CHECK-SD-NEXT: csneg w0, w1, w0, eq
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: negneg_select_nega:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w2, #0x1
|
||||
; CHECK-GI-NEXT: tst w8, #0x1
|
||||
; CHECK-GI-NEXT: csneg w8, w1, w0, eq
|
||||
; CHECK-GI-NEXT: neg w8, w8
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%nega = sub i32 0, %a
|
||||
%sel = select i1 %bb, i32 %nega, i32 %b
|
||||
%nsel = sub i32 0, %sel
|
||||
@ -28,11 +47,19 @@ define i32 @negneg_select_nega(i32 %a, i32 %b, i1 %bb) {
|
||||
}
|
||||
|
||||
define i32 @neg_select_nega(i32 %a, i32 %b, i1 %bb) {
|
||||
; CHECK-LABEL: neg_select_nega:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: tst w2, #0x1
|
||||
; CHECK-NEXT: csneg w0, w0, w1, ne
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_select_nega:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: tst w2, #0x1
|
||||
; CHECK-SD-NEXT: csneg w0, w0, w1, ne
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_select_nega:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w2, #0x1
|
||||
; CHECK-GI-NEXT: tst w8, #0x1
|
||||
; CHECK-GI-NEXT: csneg w8, w1, w0, eq
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%nega = sub i32 0, %a
|
||||
%sel = select i1 %bb, i32 %nega, i32 %b
|
||||
%res = sub i32 0, %sel
|
||||
@ -40,11 +67,19 @@ define i32 @neg_select_nega(i32 %a, i32 %b, i1 %bb) {
|
||||
}
|
||||
|
||||
define i32 @neg_select_negb(i32 %a, i32 %b, i1 %bb) {
|
||||
; CHECK-LABEL: neg_select_negb:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: tst w2, #0x1
|
||||
; CHECK-NEXT: csneg w0, w1, w0, eq
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_select_negb:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: tst w2, #0x1
|
||||
; CHECK-SD-NEXT: csneg w0, w1, w0, eq
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_select_negb:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w2, #0x1
|
||||
; CHECK-GI-NEXT: tst w8, #0x1
|
||||
; CHECK-GI-NEXT: csneg w8, w0, w1, ne
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%negb = sub i32 0, %b
|
||||
%sel = select i1 %bb, i32 %a, i32 %negb
|
||||
%res = sub i32 0, %sel
|
||||
@ -52,28 +87,47 @@ define i32 @neg_select_negb(i32 %a, i32 %b, i1 %bb) {
|
||||
}
|
||||
|
||||
define i32 @neg_select_ab(i32 %a, i32 %b, i1 %bb) {
|
||||
; CHECK-LABEL: neg_select_ab:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: tst w2, #0x1
|
||||
; CHECK-NEXT: csel w8, w0, w1, ne
|
||||
; CHECK-NEXT: neg w0, w8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_select_ab:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: tst w2, #0x1
|
||||
; CHECK-SD-NEXT: csel w8, w0, w1, ne
|
||||
; CHECK-SD-NEXT: neg w0, w8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_select_ab:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w2, #0x1
|
||||
; CHECK-GI-NEXT: tst w8, #0x1
|
||||
; CHECK-GI-NEXT: csel w8, w0, w1, ne
|
||||
; CHECK-GI-NEXT: neg w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%sel = select i1 %bb, i32 %a, i32 %b
|
||||
%res = sub i32 0, %sel
|
||||
ret i32 %res
|
||||
}
|
||||
|
||||
define i32 @neg_select_nega_with_use(i32 %a, i32 %b, i1 %bb) {
|
||||
; CHECK-LABEL: neg_select_nega_with_use:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: tst w2, #0x1
|
||||
; CHECK-NEXT: neg w8, w0
|
||||
; CHECK-NEXT: csneg w9, w1, w0, eq
|
||||
; CHECK-NEXT: sub w0, w8, w9
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: neg_select_nega_with_use:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: tst w2, #0x1
|
||||
; CHECK-SD-NEXT: neg w8, w0
|
||||
; CHECK-SD-NEXT: csneg w9, w1, w0, eq
|
||||
; CHECK-SD-NEXT: sub w0, w8, w9
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: neg_select_nega_with_use:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: and w8, w2, #0x1
|
||||
; CHECK-GI-NEXT: tst w8, #0x1
|
||||
; CHECK-GI-NEXT: neg w8, w0
|
||||
; CHECK-GI-NEXT: csneg w9, w1, w0, eq
|
||||
; CHECK-GI-NEXT: sub w0, w8, w9
|
||||
; CHECK-GI-NEXT: ret
|
||||
%nega = sub i32 0, %a
|
||||
%sel = select i1 %bb, i32 %nega, i32 %b
|
||||
%nsel = sub i32 0, %sel
|
||||
%res = add i32 %nsel, %nega
|
||||
ret i32 %res
|
||||
}
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; CHECK: {{.*}}
|
||||
|
@ -1,13 +1,31 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mattr=+dotprod < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=cortex-a65 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=cortex-a65ae < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=neoverse-e1 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=neoverse-n1 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=neoverse-n2 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=ampere1 < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=ampere1a < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mcpu=ampere1b < %s | FileCheck %s
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mattr=+dotprod < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple aarch64-none-linux-gnu -mattr=+dotprod -global-isel -global-isel-abort=2 2>&1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
; CHECK-GI: warning: Instruction selection used fallback path for test_vdot_u32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_u32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_s32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_s32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_u32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_u32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_s32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_s32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_lane_u32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_lane_u32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_laneq_u32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_laneq_u32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_lane_u32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_lane_u32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_laneq_u32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_laneq_u32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_lane_s32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_lane_s32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_laneq_s32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_laneq_s32
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_lane_s32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_lane_s32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdot_laneq_s32_zero
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for test_vdotq_laneq_s32_zero
|
||||
|
||||
declare <2 x i32> @llvm.aarch64.neon.udot.v2i32.v8i8(<2 x i32>, <8 x i8>, <8 x i8>)
|
||||
declare <4 x i32> @llvm.aarch64.neon.udot.v4i32.v16i8(<4 x i32>, <16 x i8>, <16 x i8>)
|
||||
@ -326,3 +344,6 @@ entry:
|
||||
%ret = add <4 x i32> %vdot1.i, %a
|
||||
ret <4 x i32> %ret
|
||||
}
|
||||
;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
|
||||
; CHECK-GI: {{.*}}
|
||||
; CHECK-SD: {{.*}}
|
||||
|
@ -1,12 +1,25 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc < %s -mtriple=aarch64 -mattr=+sve2 | FileCheck %s
|
||||
; RUN: llc -mtriple=aarch64-none-elf -mattr=+sve2 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-SD
|
||||
; RUN: llc -mtriple=aarch64-none-elf -mattr=+sve2 -global-isel -global-isel-abort=2 2>&1 < %s | FileCheck %s --check-prefixes=CHECK,CHECK-GI
|
||||
|
||||
; CHECK-GI: warning: Instruction selection used fallback path for smlsl_nxv8i16
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for umlsl_nxv8i16
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for mls_nxv8i16
|
||||
; CHECK-GI-NEXT: warning: Instruction selection used fallback path for mla_nxv8i16
|
||||
|
||||
define i64 @smlsl_i64(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
; CHECK-LABEL: smlsl_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: smsubl x8, w4, w3, x0
|
||||
; CHECK-NEXT: smsubl x0, w2, w1, x8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: smlsl_i64:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: smsubl x8, w4, w3, x0
|
||||
; CHECK-SD-NEXT: smsubl x0, w2, w1, x8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: smlsl_i64:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: smull x8, w2, w1
|
||||
; CHECK-GI-NEXT: smaddl x8, w4, w3, x8
|
||||
; CHECK-GI-NEXT: sub x0, x0, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%be = sext i32 %b to i64
|
||||
%ce = sext i32 %c to i64
|
||||
%de = sext i32 %d to i64
|
||||
@ -19,11 +32,18 @@ define i64 @smlsl_i64(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
}
|
||||
|
||||
define i64 @umlsl_i64(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
; CHECK-LABEL: umlsl_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: umsubl x8, w4, w3, x0
|
||||
; CHECK-NEXT: umsubl x0, w2, w1, x8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: umlsl_i64:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: umsubl x8, w4, w3, x0
|
||||
; CHECK-SD-NEXT: umsubl x0, w2, w1, x8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: umlsl_i64:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: umull x8, w2, w1
|
||||
; CHECK-GI-NEXT: umaddl x8, w4, w3, x8
|
||||
; CHECK-GI-NEXT: sub x0, x0, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%be = zext i32 %b to i64
|
||||
%ce = zext i32 %c to i64
|
||||
%de = zext i32 %d to i64
|
||||
@ -36,11 +56,18 @@ define i64 @umlsl_i64(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
}
|
||||
|
||||
define i64 @mls_i64(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e) {
|
||||
; CHECK-LABEL: mls_i64:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: msub x8, x4, x3, x0
|
||||
; CHECK-NEXT: msub x0, x2, x1, x8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: mls_i64:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: msub x8, x4, x3, x0
|
||||
; CHECK-SD-NEXT: msub x0, x2, x1, x8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: mls_i64:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mul x8, x2, x1
|
||||
; CHECK-GI-NEXT: madd x8, x4, x3, x8
|
||||
; CHECK-GI-NEXT: sub x0, x0, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%m1.neg = mul i64 %c, %b
|
||||
%m2.neg = mul i64 %e, %d
|
||||
%reass.add = add i64 %m2.neg, %m1.neg
|
||||
@ -49,11 +76,18 @@ define i64 @mls_i64(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e) {
|
||||
}
|
||||
|
||||
define i16 @mls_i16(i16 %a, i16 %b, i16 %c, i16 %d, i16 %e) {
|
||||
; CHECK-LABEL: mls_i16:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: msub w8, w4, w3, w0
|
||||
; CHECK-NEXT: msub w0, w2, w1, w8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: mls_i16:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: msub w8, w4, w3, w0
|
||||
; CHECK-SD-NEXT: msub w0, w2, w1, w8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: mls_i16:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mul w8, w2, w1
|
||||
; CHECK-GI-NEXT: madd w8, w4, w3, w8
|
||||
; CHECK-GI-NEXT: sub w0, w0, w8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%m1.neg = mul i16 %c, %b
|
||||
%m2.neg = mul i16 %e, %d
|
||||
%reass.add = add i16 %m2.neg, %m1.neg
|
||||
@ -91,12 +125,20 @@ define i64 @mls_i64_C(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e) {
|
||||
}
|
||||
|
||||
define i64 @umlsl_i64_muls(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
; CHECK-LABEL: umlsl_i64_muls:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: umull x8, w2, w3
|
||||
; CHECK-NEXT: umsubl x8, w4, w3, x8
|
||||
; CHECK-NEXT: umsubl x0, w2, w1, x8
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: umlsl_i64_muls:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: umull x8, w2, w3
|
||||
; CHECK-SD-NEXT: umsubl x8, w4, w3, x8
|
||||
; CHECK-SD-NEXT: umsubl x0, w2, w1, x8
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: umlsl_i64_muls:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: umull x8, w2, w1
|
||||
; CHECK-GI-NEXT: umull x9, w2, w3
|
||||
; CHECK-GI-NEXT: umaddl x8, w4, w3, x8
|
||||
; CHECK-GI-NEXT: sub x0, x9, x8
|
||||
; CHECK-GI-NEXT: ret
|
||||
%be = zext i32 %b to i64
|
||||
%ce = zext i32 %c to i64
|
||||
%de = zext i32 %d to i64
|
||||
@ -110,13 +152,21 @@ define i64 @umlsl_i64_muls(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
}
|
||||
|
||||
define i64 @umlsl_i64_uses(i64 %a, i32 %b, i32 %c, i32 %d, i32 %e) {
|
||||
; CHECK-LABEL: umlsl_i64_uses:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: umull x8, w4, w3
|
||||
; CHECK-NEXT: umaddl x8, w2, w1, x8
|
||||
; CHECK-NEXT: sub x9, x0, x8
|
||||
; CHECK-NEXT: and x0, x8, x9
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: umlsl_i64_uses:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: umull x8, w4, w3
|
||||
; CHECK-SD-NEXT: umaddl x8, w2, w1, x8
|
||||
; CHECK-SD-NEXT: sub x9, x0, x8
|
||||
; CHECK-SD-NEXT: and x0, x8, x9
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: umlsl_i64_uses:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: umull x8, w2, w1
|
||||
; CHECK-GI-NEXT: umaddl x8, w4, w3, x8
|
||||
; CHECK-GI-NEXT: sub x9, x0, x8
|
||||
; CHECK-GI-NEXT: and x0, x8, x9
|
||||
; CHECK-GI-NEXT: ret
|
||||
%be = zext i32 %b to i64
|
||||
%ce = zext i32 %c to i64
|
||||
%de = zext i32 %d to i64
|
||||
@ -175,11 +225,18 @@ define i64 @mla_i64_mul(i64 %a, i64 %b, i64 %c, i64 %d, i64 %e) {
|
||||
|
||||
|
||||
define <8 x i16> @smlsl_v8i16(<8 x i16> %a, <8 x i8> %b, <8 x i8> %c, <8 x i8> %d, <8 x i8> %e) {
|
||||
; CHECK-LABEL: smlsl_v8i16:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: smlsl v0.8h, v4.8b, v3.8b
|
||||
; CHECK-NEXT: smlsl v0.8h, v2.8b, v1.8b
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: smlsl_v8i16:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: smlsl v0.8h, v4.8b, v3.8b
|
||||
; CHECK-SD-NEXT: smlsl v0.8h, v2.8b, v1.8b
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: smlsl_v8i16:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: smull v1.8h, v2.8b, v1.8b
|
||||
; CHECK-GI-NEXT: smlal v1.8h, v4.8b, v3.8b
|
||||
; CHECK-GI-NEXT: sub v0.8h, v0.8h, v1.8h
|
||||
; CHECK-GI-NEXT: ret
|
||||
%be = sext <8 x i8> %b to <8 x i16>
|
||||
%ce = sext <8 x i8> %c to <8 x i16>
|
||||
%de = sext <8 x i8> %d to <8 x i16>
|
||||
@ -192,11 +249,18 @@ define <8 x i16> @smlsl_v8i16(<8 x i16> %a, <8 x i8> %b, <8 x i8> %c, <8 x i8> %
|
||||
}
|
||||
|
||||
define <8 x i16> @umlsl_v8i16(<8 x i16> %a, <8 x i8> %b, <8 x i8> %c, <8 x i8> %d, <8 x i8> %e) {
|
||||
; CHECK-LABEL: umlsl_v8i16:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: umlsl v0.8h, v4.8b, v3.8b
|
||||
; CHECK-NEXT: umlsl v0.8h, v2.8b, v1.8b
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: umlsl_v8i16:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: umlsl v0.8h, v4.8b, v3.8b
|
||||
; CHECK-SD-NEXT: umlsl v0.8h, v2.8b, v1.8b
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: umlsl_v8i16:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: umull v1.8h, v2.8b, v1.8b
|
||||
; CHECK-GI-NEXT: umlal v1.8h, v4.8b, v3.8b
|
||||
; CHECK-GI-NEXT: sub v0.8h, v0.8h, v1.8h
|
||||
; CHECK-GI-NEXT: ret
|
||||
%be = zext <8 x i8> %b to <8 x i16>
|
||||
%ce = zext <8 x i8> %c to <8 x i16>
|
||||
%de = zext <8 x i8> %d to <8 x i16>
|
||||
@ -209,11 +273,18 @@ define <8 x i16> @umlsl_v8i16(<8 x i16> %a, <8 x i8> %b, <8 x i8> %c, <8 x i8> %
|
||||
}
|
||||
|
||||
define <8 x i16> @mls_v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16> %d, <8 x i16> %e) {
|
||||
; CHECK-LABEL: mls_v8i16:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: mls v0.8h, v4.8h, v3.8h
|
||||
; CHECK-NEXT: mls v0.8h, v2.8h, v1.8h
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: mls_v8i16:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: mls v0.8h, v4.8h, v3.8h
|
||||
; CHECK-SD-NEXT: mls v0.8h, v2.8h, v1.8h
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: mls_v8i16:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mul v1.8h, v2.8h, v1.8h
|
||||
; CHECK-GI-NEXT: mla v1.8h, v4.8h, v3.8h
|
||||
; CHECK-GI-NEXT: sub v0.8h, v0.8h, v1.8h
|
||||
; CHECK-GI-NEXT: ret
|
||||
%m1.neg = mul <8 x i16> %c, %b
|
||||
%m2.neg = mul <8 x i16> %e, %d
|
||||
%reass.add = add <8 x i16> %m2.neg, %m1.neg
|
||||
@ -236,12 +307,20 @@ define <8 x i16> @mla_v8i16(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16>
|
||||
}
|
||||
|
||||
define <8 x i16> @mls_v8i16_C(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16> %d, <8 x i16> %e) {
|
||||
; CHECK-LABEL: mls_v8i16_C:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: movi v0.8h, #10
|
||||
; CHECK-NEXT: mls v0.8h, v4.8h, v3.8h
|
||||
; CHECK-NEXT: mls v0.8h, v2.8h, v1.8h
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: mls_v8i16_C:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: movi v0.8h, #10
|
||||
; CHECK-SD-NEXT: mls v0.8h, v4.8h, v3.8h
|
||||
; CHECK-SD-NEXT: mls v0.8h, v2.8h, v1.8h
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: mls_v8i16_C:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mul v0.8h, v2.8h, v1.8h
|
||||
; CHECK-GI-NEXT: movi v1.8h, #10
|
||||
; CHECK-GI-NEXT: mla v0.8h, v4.8h, v3.8h
|
||||
; CHECK-GI-NEXT: sub v0.8h, v1.8h, v0.8h
|
||||
; CHECK-GI-NEXT: ret
|
||||
%m1.neg = mul <8 x i16> %c, %b
|
||||
%m2.neg = mul <8 x i16> %e, %d
|
||||
%reass.add = add <8 x i16> %m2.neg, %m1.neg
|
||||
@ -250,13 +329,21 @@ define <8 x i16> @mls_v8i16_C(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16
|
||||
}
|
||||
|
||||
define <8 x i16> @mla_v8i16_C(<8 x i16> %a, <8 x i16> %b, <8 x i16> %c, <8 x i16> %d, <8 x i16> %e) {
|
||||
; CHECK-LABEL: mla_v8i16_C:
|
||||
; CHECK: // %bb.0:
|
||||
; CHECK-NEXT: mul v1.8h, v2.8h, v1.8h
|
||||
; CHECK-NEXT: movi v0.8h, #10
|
||||
; CHECK-NEXT: mla v1.8h, v4.8h, v3.8h
|
||||
; CHECK-NEXT: add v0.8h, v1.8h, v0.8h
|
||||
; CHECK-NEXT: ret
|
||||
; CHECK-SD-LABEL: mla_v8i16_C:
|
||||
; CHECK-SD: // %bb.0:
|
||||
; CHECK-SD-NEXT: mul v1.8h, v2.8h, v1.8h
|
||||
; CHECK-SD-NEXT: movi v0.8h, #10
|
||||
; CHECK-SD-NEXT: mla v1.8h, v4.8h, v3.8h
|
||||
; CHECK-SD-NEXT: add v0.8h, v1.8h, v0.8h
|
||||
; CHECK-SD-NEXT: ret
|
||||
;
|
||||
; CHECK-GI-LABEL: mla_v8i16_C:
|
||||
; CHECK-GI: // %bb.0:
|
||||
; CHECK-GI-NEXT: mul v0.8h, v2.8h, v1.8h
|
||||
; CHECK-GI-NEXT: movi v1.8h, #10
|
||||
; CHECK-GI-NEXT: mla v0.8h, v4.8h, v3.8h
|
||||
; CHECK-GI-NEXT: add v0.8h, v1.8h, v0.8h
|
||||
; CHECK-GI-NEXT: ret
|
||||
%m1.neg = mul <8 x i16> %c, %b
|
||||
%m2.neg = mul <8 x i16> %e, %d
|
||||
%reass.add = add <8 x i16> %m2.neg, %m1.neg
|
||||
|
Loading…
x
Reference in New Issue
Block a user