brintos

brintos / llvm-project-archived public Read only

0
0
Text · 8.1 KiB · b6e6e61 Raw
301 lines · plain
1; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -mattr=+lvi-cfi < %s | FileCheck %s --check-prefix=X642; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -mattr=+lvi-cfi -O0 < %s | FileCheck %s --check-prefix=X64FAST3;4; Note that a lot of this code was lifted from retpoline.ll.5 6declare dso_local void @bar(i32)7 8; Test a simple indirect call and tail call.9define void @icall_reg(ptr %fp, i32 %x) {10entry:11  tail call void @bar(i32 %x)12  tail call void %fp(i32 %x)13  tail call void @bar(i32 %x)14  tail call void %fp(i32 %x)15  ret void16}17 18; X64-LABEL: icall_reg:19; X64-DAG:   movq %rdi, %[[fp:[^ ]*]]20; X64-DAG:   movl %esi, %[[x:[^ ]*]]21; X64:       movl %esi, %edi22; X64:       callq bar23; X64-DAG:   movl %[[x]], %edi24; X64-DAG:   movq %[[fp]], %r1125; X64:       cs26; X64-NEXT:  callq __llvm_lvi_thunk_r1127; X64:       movl %[[x]], %edi28; X64:       callq bar29; X64-DAG:   movl %[[x]], %edi30; X64-DAG:   movq %[[fp]], %r1131; X64:       cs32; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL33 34; X64FAST-LABEL: icall_reg:35; X64FAST:       callq bar36; X64FAST:       cs37; X64FAST-NEXT:  callq __llvm_lvi_thunk_r1138; X64FAST:       callq bar39; X64FAST:       cs40; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL41 42 43@global_fp = external dso_local global ptr44 45; Test an indirect call through a global variable.46define void @icall_global_fp(i32 %x, ptr %fpp) #0 {47  %fp1 = load ptr, ptr @global_fp48  call void %fp1(i32 %x)49  %fp2 = load ptr, ptr @global_fp50  tail call void %fp2(i32 %x)51  ret void52}53 54; X64-LABEL: icall_global_fp:55; X64-DAG:   movl %edi, %[[x:[^ ]*]]56; X64-DAG:   movq global_fp(%rip), %r1157; X64:       cs58; X64-NEXT:  callq __llvm_lvi_thunk_r1159; X64-DAG:   movl %[[x]], %edi60; X64-DAG:   movq global_fp(%rip), %r1161; X64:       cs62; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL63 64; X64FAST-LABEL: icall_global_fp:65; X64FAST:       movq global_fp(%rip), %r1166; X64FAST:       cs67; X64FAST-NEXT:  callq __llvm_lvi_thunk_r1168; X64FAST:       movq global_fp(%rip), %r1169; X64FAST:       cs70; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL71 72 73%struct.Foo = type { ptr }74 75; Test an indirect call through a vtable.76define void @vcall(ptr %obj) #0 {77  %vptr = load ptr, ptr %obj78  %vslot = getelementptr ptr, ptr %vptr, i32 179  %fp = load ptr, ptr %vslot80  tail call void %fp(ptr %obj)81  tail call void %fp(ptr %obj)82  ret void83}84 85; X64-LABEL: vcall:86; X64:       movq %rdi, %[[obj:[^ ]*]]87; X64:       movq (%rdi), %[[vptr:[^ ]*]]88; X64:       movq 8(%[[vptr]]), %[[fp:[^ ]*]]89; X64:       movq %[[fp]], %r1190; X64:       cs91; X64-NEXT:  callq __llvm_lvi_thunk_r1192; X64-DAG:   movq %[[obj]], %rdi93; X64-DAG:   movq %[[fp]], %r1194; X64:       cs95; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL96 97; X64FAST-LABEL: vcall:98; X64FAST:       cs99; X64FAST-NEXT:  callq __llvm_lvi_thunk_r11100; X64FAST:       cs101; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL102 103 104declare dso_local void @direct_callee()105 106define void @direct_tail() #0 {107  tail call void @direct_callee()108  ret void109}110 111; X64-LABEL: direct_tail:112; X64:       jmp direct_callee # TAILCALL113; X64FAST-LABEL: direct_tail:114; X64FAST:   jmp direct_callee # TAILCALL115 116 117declare void @nonlazybind_callee() #1118 119define void @nonlazybind_caller() #0 {120  call void @nonlazybind_callee()121  tail call void @nonlazybind_callee()122  ret void123}124 125; X64-LABEL: nonlazybind_caller:126; X64:       movq nonlazybind_callee@GOTPCREL(%rip), %[[REG:.*]]127; X64:       movq %[[REG]], %r11128; X64:       cs129; X64-NEXT:  callq __llvm_lvi_thunk_r11130; X64:       movq %[[REG]], %r11131; X64:       cs132; X64-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL133; X64FAST-LABEL: nonlazybind_caller:134; X64FAST:   movq nonlazybind_callee@GOTPCREL(%rip), %r11135; X64FAST:   cs136; X64FAST-NEXT:  callq __llvm_lvi_thunk_r11137; X64FAST:   movq nonlazybind_callee@GOTPCREL(%rip), %r11138; X64FAST:   cs139; X64FAST-NEXT:  jmp __llvm_lvi_thunk_r11 # TAILCALL140 141 142; Check that a switch gets lowered using a jump table143define void @switch_jumptable(ptr %ptr, ptr %sink) #0 {144; X64-LABEL: switch_jumptable:145; X64-NOT:      jmpq *146entry:147  br label %header148 149header:150  %i = load volatile i32, ptr %ptr151  switch i32 %i, label %bb0 [152    i32 1, label %bb1153    i32 2, label %bb2154    i32 3, label %bb3155    i32 4, label %bb4156    i32 5, label %bb5157    i32 6, label %bb6158    i32 7, label %bb7159    i32 8, label %bb8160    i32 9, label %bb9161  ]162 163bb0:164  store volatile i64 0, ptr %sink165  br label %header166 167bb1:168  store volatile i64 1, ptr %sink169  br label %header170 171bb2:172  store volatile i64 2, ptr %sink173  br label %header174 175bb3:176  store volatile i64 3, ptr %sink177  br label %header178 179bb4:180  store volatile i64 4, ptr %sink181  br label %header182 183bb5:184  store volatile i64 5, ptr %sink185  br label %header186 187bb6:188  store volatile i64 6, ptr %sink189  br label %header190 191bb7:192  store volatile i64 7, ptr %sink193  br label %header194 195bb8:196  store volatile i64 8, ptr %sink197  br label %header198 199bb9:200  store volatile i64 9, ptr %sink201  br label %header202}203 204 205@indirectbr_rewrite.targets = constant [10 x ptr] [ptr blockaddress(@indirectbr_rewrite, %bb0),206                                                   ptr blockaddress(@indirectbr_rewrite, %bb1),207                                                   ptr blockaddress(@indirectbr_rewrite, %bb2),208                                                   ptr blockaddress(@indirectbr_rewrite, %bb3),209                                                   ptr blockaddress(@indirectbr_rewrite, %bb4),210                                                   ptr blockaddress(@indirectbr_rewrite, %bb5),211                                                   ptr blockaddress(@indirectbr_rewrite, %bb6),212                                                   ptr blockaddress(@indirectbr_rewrite, %bb7),213                                                   ptr blockaddress(@indirectbr_rewrite, %bb8),214                                                   ptr blockaddress(@indirectbr_rewrite, %bb9)]215 216; Check that when thunks are enabled the indirectbr instruction gets217; rewritten to use switch, and that in turn doesn't get lowered as a jump218; table.219define void @indirectbr_rewrite(ptr readonly %p, ptr %sink) #0 {220; X64-LABEL: indirectbr_rewrite:221; X64-NOT:     jmpq *222entry:223  %i0 = load i64, ptr %p224  %target.i0 = getelementptr [10 x ptr], ptr @indirectbr_rewrite.targets, i64 0, i64 %i0225  %target0 = load ptr, ptr %target.i0226  indirectbr ptr %target0, [label %bb1, label %bb3]227 228bb0:229  store volatile i64 0, ptr %sink230  br label %latch231 232bb1:233  store volatile i64 1, ptr %sink234  br label %latch235 236bb2:237  store volatile i64 2, ptr %sink238  br label %latch239 240bb3:241  store volatile i64 3, ptr %sink242  br label %latch243 244bb4:245  store volatile i64 4, ptr %sink246  br label %latch247 248bb5:249  store volatile i64 5, ptr %sink250  br label %latch251 252bb6:253  store volatile i64 6, ptr %sink254  br label %latch255 256bb7:257  store volatile i64 7, ptr %sink258  br label %latch259 260bb8:261  store volatile i64 8, ptr %sink262  br label %latch263 264bb9:265  store volatile i64 9, ptr %sink266  br label %latch267 268latch:269  %i.next = load i64, ptr %p270  %target.i.next = getelementptr [10 x ptr], ptr @indirectbr_rewrite.targets, i64 0, i64 %i.next271  %target.next = load ptr, ptr %target.i.next272  ; Potentially hit a full 10 successors here so that even if we rewrite as273  ; a switch it will try to be lowered with a jump table.274  indirectbr ptr %target.next, [label %bb0,275                                label %bb1,276                                label %bb2,277                                label %bb3,278                                label %bb4,279                                label %bb5,280                                label %bb6,281                                label %bb7,282                                label %bb8,283                                label %bb9]284}285 286; Lastly check that the necessary thunks were emitted.287;288; X64-LABEL:         .section        .text.__llvm_lvi_thunk_r11,{{.*}},__llvm_lvi_thunk_r11,comdat289; X64-NEXT:          .hidden __llvm_lvi_thunk_r11290; X64-NEXT:          .weak   __llvm_lvi_thunk_r11291; X64:       __llvm_lvi_thunk_r11:292; X64-NEXT:  # {{.*}}                                # %entry293; X64-NEXT:          lfence294; X64-NEXT:          jmpq     *%r11295 296attributes #1 = { nonlazybind }297 298!llvm.module.flags = !{!0}299 300!0 = !{i32 4, !"indirect_branch_cs_prefix", i32 1}301