aboutsummaryrefslogtreecommitdiff
path: root/llvm/test/CodeGen/ARM
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/CodeGen/ARM')
-rw-r--r--llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll39
-rw-r--r--llvm/test/CodeGen/ARM/call-graph-section-assembly.ll63
-rw-r--r--llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll34
-rw-r--r--llvm/test/CodeGen/ARM/call-graph-section.ll37
-rw-r--r--llvm/test/CodeGen/ARM/fp16-promote.ll50
5 files changed, 183 insertions, 40 deletions
diff --git a/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll b/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll
new file mode 100644
index 0000000..a2d6ca9
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/call-graph-section-addrtaken.ll
@@ -0,0 +1,39 @@
+;; Test if a potential indirect call target function which has internal linkage and
+;; address taken has its type ID emitted to callgraph section.
+;; This test also makes sure that callback functions which meet the above constraint
+;; are handled correctly.
+
+; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -o - < %s | FileCheck %s
+
+declare !type !0 void @_Z6doWorkPFviE(ptr)
+
+define i32 @_Z4testv() !type !1 {
+entry:
+ call void @_Z6doWorkPFviE(ptr nonnull @_ZL10myCallbacki)
+ ret i32 0
+}
+
+; CHECK: _ZL10myCallbacki:
+; CHECK-NEXT: [[LABEL_FUNC:\.Lfunc_begin[0-9]+]]:
+define internal void @_ZL10myCallbacki(i32 %value) !type !2 {
+entry:
+ %sink = alloca i32, align 4
+ store volatile i32 %value, ptr %sink, align 4
+ %i1 = load volatile i32, ptr %sink, align 4
+ ret void
+}
+
+!0 = !{i64 0, !"_ZTSFvPFviEE.generalized"}
+!1 = !{i64 0, !"_ZTSFivE.generalized"}
+!2 = !{i64 0, !"_ZTSFviE.generalized"}
+
+; CHECK: .section .callgraph,"o",%progbits,.text
+;; Version
+; CHECK-NEXT: .byte 0
+;; Flags -- Potential indirect target so LSB is set to 1. Other bits are 0.
+; CHECK-NEXT: .byte 1
+;; Function Entry PC
+; CHECK-NEXT: .long [[LABEL_FUNC]]
+;; Function type ID -5212364466660467813
+; CHECK-NEXT: .long 1154849691
+; CHECK-NEXT: .long 3081369122
diff --git a/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll b/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll
new file mode 100644
index 0000000..bf5249e
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/call-graph-section-assembly.ll
@@ -0,0 +1,63 @@
+;; Test if temporary labels are generated for each indirect callsite.
+;; Test if the .callgraph section contains the MD5 hash of callees' type (type id)
+;; is correctly paired with its corresponding temporary label generated for indirect
+;; call sites annotated with !callee_type metadata.
+;; Test if the .callgraph section contains unique direct callees.
+
+; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -o - < %s | FileCheck %s
+
+declare !type !0 void @direct_foo()
+declare !type !1 i32 @direct_bar(i8)
+declare !type !2 ptr @direct_baz(ptr)
+
+; CHECK: ball:
+; CHECK-NEXT: [[LABEL_FUNC:\.Lfunc_begin[0-9]+]]:
+define ptr @ball() {
+entry:
+ call void @direct_foo()
+ %fp_foo_val = load ptr, ptr null, align 8
+ call void (...) %fp_foo_val(), !callee_type !0
+ call void @direct_foo()
+ %fp_bar_val = load ptr, ptr null, align 8
+ %call_fp_bar = call i32 %fp_bar_val(i8 0), !callee_type !2
+ %call_fp_bar_direct = call i32 @direct_bar(i8 1)
+ %fp_baz_val = load ptr, ptr null, align 8
+ %call_fp_baz = call ptr %fp_baz_val(ptr null), !callee_type !4
+ call void @direct_foo()
+ %call_fp_baz_direct = call ptr @direct_baz(ptr null)
+ call void @direct_foo()
+ ret ptr %call_fp_baz
+}
+
+!0 = !{!1}
+!1 = !{i64 0, !"_ZTSFvE.generalized"}
+!2 = !{!3}
+!3 = !{i64 0, !"_ZTSFicE.generalized"}
+!4 = !{!5}
+!5 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+
+; CHECK: .section .callgraph,"o",%progbits,.text
+;; Version
+; CHECK-NEXT: .byte 0
+;; Flags
+; CHECK-NEXT: .byte 7
+;; Function Entry PC
+; CHECK-NEXT: .long [[LABEL_FUNC]]
+;; Function type ID -- set to 0 as no type metadata attached to function.
+; CHECK-NEXT: .long 0
+; CHECK-NEXT: .long 0
+;; Number of unique direct callees.
+; CHECK-NEXT: .byte 3
+;; Direct callees.
+; CHECK-NEXT: .long direct_foo
+; CHECK-NEXT: .long direct_bar
+; CHECK-NEXT: .long direct_baz
+;; Number of unique indirect target type IDs.
+; CHECK-NEXT: .byte 3
+;; Indirect type IDs.
+; CHECK-NEXT: .long 838288420
+; CHECK-NEXT: .long 1053552373
+; CHECK-NEXT: .long 1505527380
+; CHECK-NEXT: .long 814631809
+; CHECK-NEXT: .long 342417018
+; CHECK-NEXT: .long 2013108216
diff --git a/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll b/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll
new file mode 100644
index 0000000..d577603
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/call-graph-section-tailcall.ll
@@ -0,0 +1,34 @@
+;; Tests that we store the type identifiers in .callgraph section of the object file for tailcalls.
+
+; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llvm-readelf -x .callgraph - | FileCheck %s
+
+define i32 @check_tailcall(ptr %func, i8 %x) !type !0 {
+entry:
+ %call = tail call i32 %func(i8 signext %x), !callee_type !1
+ ret i32 %call
+}
+
+define i32 @main(i32 %argc) !type !3 {
+entry:
+ %andop = and i32 %argc, 1
+ %cmp = icmp eq i32 %andop, 0
+ %foo.bar = select i1 %cmp, ptr @foo, ptr @bar
+ %call.i = tail call i32 %foo.bar(i8 signext 97), !callee_type !1
+ ret i32 %call.i
+}
+
+declare !type !2 i32 @foo(i8 signext)
+
+declare !type !2 i32 @bar(i8 signext)
+
+!0 = !{i64 0, !"_ZTSFiPvcE.generalized"}
+!1 = !{!2}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{i64 0, !"_ZTSFiiE.generalized"}
+
+; CHECK: Hex dump of section '.callgraph':
+; CHECK-NEXT: 0x00000000 00050000 00008e19 0b7f3326 e3000154
+; CHECK-NEXT: 0x00000010 86bc5981 4b8e3000 05100000 00a150b8
+;; Verify that the type id 0x308e4b8159bc8654 is in section.
+; CHECK-NEXT: 0x00000020 3e0cfe3c b2015486 bc59814b 8e30
diff --git a/llvm/test/CodeGen/ARM/call-graph-section.ll b/llvm/test/CodeGen/ARM/call-graph-section.ll
new file mode 100644
index 0000000..928a1067
--- /dev/null
+++ b/llvm/test/CodeGen/ARM/call-graph-section.ll
@@ -0,0 +1,37 @@
+;; Tests that we store the type identifiers in .callgraph section of the object file.
+
+; RUN: llc -mtriple=arm-unknown-linux --call-graph-section -filetype=obj -o - < %s | \
+; RUN: llvm-readelf -x .callgraph - | FileCheck %s
+
+declare !type !0 void @foo()
+
+declare !type !1 i32 @bar(i8)
+
+declare !type !2 ptr @baz(ptr)
+
+define void @main() {
+entry:
+ %fp_foo_val = load ptr, ptr null, align 8
+ call void (...) %fp_foo_val(), !callee_type !1
+ %fp_bar_val = load ptr, ptr null, align 8
+ %call_fp_bar = call i32 %fp_bar_val(i8 0), !callee_type !3
+ %fp_baz_val = load ptr, ptr null, align 8
+ %call_fp_baz = call ptr %fp_baz_val(ptr null), !callee_type !4
+ ret void
+}
+
+;; Check that the numeric type id (md5 hash) for the below type ids are emitted
+;; to the callgraph section.
+!0 = !{i64 0, !"_ZTSFvE.generalized"}
+!1 = !{!0}
+!2 = !{i64 0, !"_ZTSFicE.generalized"}
+!3 = !{!2}
+!4 = !{!5}
+!5 = !{i64 0, !"_ZTSFPvS_E.generalized"}
+
+;; Make sure following type IDs are in call graph section
+;; 0x5eecb3e2444f731f, 0x814b8e305486bc59, 0xf897fd777ade6814
+; CHECK: Hex dump of section '.callgraph':
+; CHECK-NEXT: 0x00000000 00050000 00000000 00000000 00000324
+; CHECK-NEXT: 0x00000010 44f731f5 eecb3e54 86bc5981 4b8e307a
+; CHECK-NEXT: 0x00000020 de6814f8 97fd77
diff --git a/llvm/test/CodeGen/ARM/fp16-promote.ll b/llvm/test/CodeGen/ARM/fp16-promote.ll
index 800ee87..8230e47 100644
--- a/llvm/test/CodeGen/ARM/fp16-promote.ll
+++ b/llvm/test/CodeGen/ARM/fp16-promote.ll
@@ -1572,26 +1572,11 @@ define void @test_fma(ptr %p, ptr %q, ptr %r) #0 {
}
define void @test_fabs(ptr %p) {
-; CHECK-FP16-LABEL: test_fabs:
-; CHECK-FP16: ldrh r1, [r0]
-; CHECK-FP16-NEXT: vmov s0, r1
-; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0
-; CHECK-FP16-NEXT: vabs.f32 s0, s0
-; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0
-; CHECK-FP16-NEXT: vmov r1, s0
-; CHECK-FP16-NEXT: strh r1, [r0]
-; CHECK-FP16-NEXT: bx lr
-;
-; CHECK-LIBCALL-LABEL: test_fabs:
-; CHECK-LIBCALL: .save {r4, lr}
-; CHECK-LIBCALL-NEXT: push {r4, lr}
-; CHECK-LIBCALL-NEXT: mov r4, r0
-; CHECK-LIBCALL-NEXT: ldrh r0, [r0]
-; CHECK-LIBCALL-NEXT: bl __aeabi_h2f
-; CHECK-LIBCALL-NEXT: bic r0, r0, #-2147483648
-; CHECK-LIBCALL-NEXT: bl __aeabi_f2h
-; CHECK-LIBCALL-NEXT: strh r0, [r4]
-; CHECK-LIBCALL-NEXT: pop {r4, pc}
+; CHECK-ALL-LABEL: test_fabs:
+; CHECK-ALL: ldrh r1, [r0]
+; CHECK-ALL-NEXT: bfc r1, #15, #17
+; CHECK-ALL-NEXT: strh r1, [r0]
+; CHECK-ALL-NEXT: bx lr
%a = load half, ptr %p, align 2
%r = call half @llvm.fabs.f16(half %a)
store half %r, ptr %p
@@ -2454,26 +2439,11 @@ define half @test_sitofp_i32_fadd(i32 %a, half %b) #0 {
}
define void @test_fneg(ptr %p1, ptr %p2) #0 {
-; CHECK-FP16-LABEL: test_fneg:
-; CHECK-FP16: ldrh r0, [r0]
-; CHECK-FP16-NEXT: vmov s0, r0
-; CHECK-FP16-NEXT: vcvtb.f32.f16 s0, s0
-; CHECK-FP16-NEXT: vneg.f32 s0, s0
-; CHECK-FP16-NEXT: vcvtb.f16.f32 s0, s0
-; CHECK-FP16-NEXT: vmov r0, s0
-; CHECK-FP16-NEXT: strh r0, [r1]
-; CHECK-FP16-NEXT: bx lr
-;
-; CHECK-LIBCALL-LABEL: test_fneg:
-; CHECK-LIBCALL: .save {r4, lr}
-; CHECK-LIBCALL-NEXT: push {r4, lr}
-; CHECK-LIBCALL-NEXT: ldrh r0, [r0]
-; CHECK-LIBCALL-NEXT: mov r4, r1
-; CHECK-LIBCALL-NEXT: bl __aeabi_h2f
-; CHECK-LIBCALL-NEXT: eor r0, r0, #-2147483648
-; CHECK-LIBCALL-NEXT: bl __aeabi_f2h
-; CHECK-LIBCALL-NEXT: strh r0, [r4]
-; CHECK-LIBCALL-NEXT: pop {r4, pc}
+; CHECK-ALL-LABEL: test_fneg:
+; CHECK-ALL: ldrh r0, [r0]
+; CHECK-ALL-NEXT: eor r0, r0, #32768
+; CHECK-ALL-NEXT: strh r0, [r1]
+; CHECK-ALL-NEXT: bx lr
%v = load half, ptr %p1, align 2
%res = fneg half %v
store half %res, ptr %p2, align 2