brintos

brintos / llvm-project-archived public Read only

0
0
Text · 17.2 KiB · ea9c9bc Raw
516 lines · plain
1; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown < %s | FileCheck %s --implicit-check-not="jmp.*\*" --implicit-check-not="call.*\*" --check-prefix=X642; RUN: llc -verify-machineinstrs -mtriple=x86_64-unknown -O0 < %s | FileCheck %s --implicit-check-not="jmp.*\*" --implicit-check-not="call.*\*" --check-prefix=X64FAST3 4; RUN: llc -verify-machineinstrs -mtriple=i686-unknown < %s | FileCheck %s --implicit-check-not="jmp.*\*" --implicit-check-not="call.*\*" --check-prefix=X865; RUN: llc -verify-machineinstrs -mtriple=i686-unknown -O0 < %s | FileCheck %s --implicit-check-not="jmp.*\*" --implicit-check-not="call.*\*" --check-prefix=X86FAST6 7declare void @bar(i32)8 9; Test a simple indirect call and tail call.10define void @icall_reg(ptr %fp, i32 %x) #0 {11entry:12  tail call void @bar(i32 %x)13  tail call void %fp(i32 %x)14  tail call void @bar(i32 %x)15  tail call void %fp(i32 %x)16  ret void17}18 19; X64-LABEL: icall_reg:20; X64-DAG:   movq %rdi, %[[fp:[^ ]*]]21; X64-DAG:   movl %esi, %[[x:[^ ]*]]22; X64:       movl %esi, %edi23; X64:       callq bar24; X64-DAG:   movl %[[x]], %edi25; X64-DAG:   movq %[[fp]], %r1126; X64:       callq __llvm_retpoline_r1127; X64:       movl %[[x]], %edi28; X64:       callq bar29; X64-DAG:   movl %[[x]], %edi30; X64-DAG:   movq %[[fp]], %r1131; X64:       jmp __llvm_retpoline_r11 # TAILCALL32 33; X64FAST-LABEL: icall_reg:34; X64FAST:       callq bar35; X64FAST:       callq __llvm_retpoline_r1136; X64FAST:       callq bar37; X64FAST:       jmp __llvm_retpoline_r11 # TAILCALL38 39; X86-LABEL: icall_reg:40; X86-DAG:   movl 12(%esp), %[[fp:[^ ]*]]41; X86-DAG:   movl 16(%esp), %[[x:[^ ]*]]42; X86:       pushl %[[x]]43; X86:       calll bar44; X86:       movl %[[fp]], %eax45; X86:       pushl %[[x]]46; X86:       calll __llvm_retpoline_eax47; X86:       pushl %[[x]]48; X86:       calll bar49; X86:       movl %[[fp]], %eax50; X86:       pushl %[[x]]51; X86:       calll __llvm_retpoline_eax52; X86-NOT:   # TAILCALL53 54; X86FAST-LABEL: icall_reg:55; X86FAST:       calll bar56; X86FAST:       calll __llvm_retpoline_eax57; X86FAST:       calll bar58; X86FAST:       calll __llvm_retpoline_eax59 60 61@global_fp = external dso_local global ptr62 63; Test an indirect call through a global variable.64define void @icall_global_fp(i32 %x, ptr %fpp) #0 {65  %fp1 = load ptr, ptr @global_fp66  call void %fp1(i32 %x)67  %fp2 = load ptr, ptr @global_fp68  tail call void %fp2(i32 %x)69  ret void70}71 72; X64-LABEL: icall_global_fp:73; X64-DAG:   movl %edi, %[[x:[^ ]*]]74; X64-DAG:   movq global_fp(%rip), %r1175; X64:       callq __llvm_retpoline_r1176; X64-DAG:   movl %[[x]], %edi77; X64-DAG:   movq global_fp(%rip), %r1178; X64:       jmp __llvm_retpoline_r11 # TAILCALL79 80; X64FAST-LABEL: icall_global_fp:81; X64FAST:       movq global_fp(%rip), %r1182; X64FAST:       callq __llvm_retpoline_r1183; X64FAST:       movq global_fp(%rip), %r1184; X64FAST:       jmp __llvm_retpoline_r11 # TAILCALL85 86; X86-LABEL: icall_global_fp:87; X86:       movl global_fp, %eax88; X86:       pushl 4(%esp)89; X86:       calll __llvm_retpoline_eax90; X86:       addl $4, %esp91; X86:       movl global_fp, %eax92; X86:       jmp __llvm_retpoline_eax # TAILCALL93 94; X86FAST-LABEL: icall_global_fp:95; X86FAST:       calll __llvm_retpoline_eax96; X86FAST:       jmp __llvm_retpoline_eax # TAILCALL97 98 99%struct.Foo = type { ptr }100 101; Test an indirect call through a vtable.102define void @vcall(ptr %obj) #0 {103  %vptr = load ptr, ptr %obj104  %vslot = getelementptr ptr, ptr %vptr, i32 1105  %fp = load ptr, ptr %vslot106  tail call void %fp(ptr %obj)107  tail call void %fp(ptr %obj)108  ret void109}110 111; X64-LABEL: vcall:112; X64:       movq %rdi, %[[obj:[^ ]*]]113; X64:       movq (%rdi), %[[vptr:[^ ]*]]114; X64:       movq 8(%[[vptr]]), %[[fp:[^ ]*]]115; X64:       movq %[[fp]], %r11116; X64:       callq __llvm_retpoline_r11117; X64-DAG:   movq %[[obj]], %rdi118; X64-DAG:   movq %[[fp]], %r11119; X64:       jmp __llvm_retpoline_r11 # TAILCALL120 121; X64FAST-LABEL: vcall:122; X64FAST:       callq __llvm_retpoline_r11123; X64FAST:       jmp __llvm_retpoline_r11 # TAILCALL124 125; X86-LABEL: vcall:126; X86:       movl 8(%esp), %[[obj:[^ ]*]]127; X86:       movl (%[[obj]]), %[[vptr:[^ ]*]]128; X86:       movl 4(%[[vptr]]), %[[fp:[^ ]*]]129; X86:       movl %[[fp]], %eax130; X86:       pushl %[[obj]]131; X86:       calll __llvm_retpoline_eax132; X86:       addl $4, %esp133; X86:       movl %[[fp]], %eax134; X86:       jmp __llvm_retpoline_eax # TAILCALL135 136; X86FAST-LABEL: vcall:137; X86FAST:       calll __llvm_retpoline_eax138; X86FAST:       jmp __llvm_retpoline_eax # TAILCALL139 140 141declare void @direct_callee()142 143define void @direct_tail() #0 {144  tail call void @direct_callee()145  ret void146}147 148; X64-LABEL: direct_tail:149; X64:       jmp direct_callee@PLT # TAILCALL150; X64FAST-LABEL: direct_tail:151; X64FAST:   jmp direct_callee@PLT # TAILCALL152; X86-LABEL: direct_tail:153; X86:       jmp direct_callee@PLT # TAILCALL154; X86FAST-LABEL: direct_tail:155; X86FAST:   jmp direct_callee@PLT # TAILCALL156 157 158declare void @nonlazybind_callee() #2159 160define void @nonlazybind_caller() #0 {161  call void @nonlazybind_callee()162  tail call void @nonlazybind_callee()163  ret void164}165 166; X64-LABEL: nonlazybind_caller:167; X64:       movq nonlazybind_callee@GOTPCREL(%rip), %[[REG:.*]]168; X64:       movq %[[REG]], %r11169; X64:       callq __llvm_retpoline_r11170; X64:       movq %[[REG]], %r11171; X64:       jmp __llvm_retpoline_r11 # TAILCALL172; X64FAST-LABEL: nonlazybind_caller:173; X64FAST:   movq nonlazybind_callee@GOTPCREL(%rip), %r11174; X64FAST:   callq __llvm_retpoline_r11175; X64FAST:   movq nonlazybind_callee@GOTPCREL(%rip), %r11176; X64FAST:   jmp __llvm_retpoline_r11 # TAILCALL177; X86-LABEL: nonlazybind_caller:178; X86:       calll nonlazybind_callee@PLT179; X86:       jmp nonlazybind_callee@PLT # TAILCALL180; X86FAST-LABEL: nonlazybind_caller:181; X86FAST:   calll nonlazybind_callee@PLT182; X86FAST:   jmp nonlazybind_callee@PLT # TAILCALL183 184 185; Check that a switch gets lowered using a jump table when retpolines are only186; enabled for calls.187define void @switch_jumptable(ptr %ptr, ptr %sink) #0 {188; X64-LABEL: switch_jumptable:189; X64:         jmpq *190; X86-LABEL: switch_jumptable:191; X86:         jmpl *192entry:193  br label %header194 195header:196  %i = load volatile i32, ptr %ptr197  switch i32 %i, label %bb0 [198    i32 1, label %bb1199    i32 2, label %bb2200    i32 3, label %bb3201    i32 4, label %bb4202    i32 5, label %bb5203    i32 6, label %bb6204    i32 7, label %bb7205    i32 8, label %bb8206    i32 9, label %bb9207  ]208 209bb0:210  store volatile i64 0, ptr %sink211  br label %header212 213bb1:214  store volatile i64 1, ptr %sink215  br label %header216 217bb2:218  store volatile i64 2, ptr %sink219  br label %header220 221bb3:222  store volatile i64 3, ptr %sink223  br label %header224 225bb4:226  store volatile i64 4, ptr %sink227  br label %header228 229bb5:230  store volatile i64 5, ptr %sink231  br label %header232 233bb6:234  store volatile i64 6, ptr %sink235  br label %header236 237bb7:238  store volatile i64 7, ptr %sink239  br label %header240 241bb8:242  store volatile i64 8, ptr %sink243  br label %header244 245bb9:246  store volatile i64 9, ptr %sink247  br label %header248}249 250 251@indirectbr_preserved.targets = constant [10 x ptr] [ptr blockaddress(@indirectbr_preserved, %bb0),252                                                     ptr blockaddress(@indirectbr_preserved, %bb1),253                                                     ptr blockaddress(@indirectbr_preserved, %bb2),254                                                     ptr blockaddress(@indirectbr_preserved, %bb3),255                                                     ptr blockaddress(@indirectbr_preserved, %bb4),256                                                     ptr blockaddress(@indirectbr_preserved, %bb5),257                                                     ptr blockaddress(@indirectbr_preserved, %bb6),258                                                     ptr blockaddress(@indirectbr_preserved, %bb7),259                                                     ptr blockaddress(@indirectbr_preserved, %bb8),260                                                     ptr blockaddress(@indirectbr_preserved, %bb9)]261 262; Check that we preserve indirectbr when only calls are retpolined.263define void @indirectbr_preserved(ptr readonly %p, ptr %sink) #0 {264; X64-LABEL: indirectbr_preserved:265; X64:         jmpq *266; X86-LABEL: indirectbr_preserved:267; X86:         jmpl *268entry:269  %i0 = load i64, ptr %p270  %target.i0 = getelementptr [10 x ptr], ptr @indirectbr_preserved.targets, i64 0, i64 %i0271  %target0 = load ptr, ptr %target.i0272  indirectbr ptr %target0, [label %bb1, label %bb3]273 274bb0:275  store volatile i64 0, ptr %sink276  br label %latch277 278bb1:279  store volatile i64 1, ptr %sink280  br label %latch281 282bb2:283  store volatile i64 2, ptr %sink284  br label %latch285 286bb3:287  store volatile i64 3, ptr %sink288  br label %latch289 290bb4:291  store volatile i64 4, ptr %sink292  br label %latch293 294bb5:295  store volatile i64 5, ptr %sink296  br label %latch297 298bb6:299  store volatile i64 6, ptr %sink300  br label %latch301 302bb7:303  store volatile i64 7, ptr %sink304  br label %latch305 306bb8:307  store volatile i64 8, ptr %sink308  br label %latch309 310bb9:311  store volatile i64 9, ptr %sink312  br label %latch313 314latch:315  %i.next = load i64, ptr %p316  %target.i.next = getelementptr [10 x ptr], ptr @indirectbr_preserved.targets, i64 0, i64 %i.next317  %target.next = load ptr, ptr %target.i.next318  ; Potentially hit a full 10 successors here so that even if we rewrite as319  ; a switch it will try to be lowered with a jump table.320  indirectbr ptr %target.next, [label %bb0,321                                label %bb1,322                                label %bb2,323                                label %bb3,324                                label %bb4,325                                label %bb5,326                                label %bb6,327                                label %bb7,328                                label %bb8,329                                label %bb9]330}331 332@indirectbr_rewrite.targets = constant [10 x ptr] [ptr blockaddress(@indirectbr_rewrite, %bb0),333                                                   ptr blockaddress(@indirectbr_rewrite, %bb1),334                                                   ptr blockaddress(@indirectbr_rewrite, %bb2),335                                                   ptr blockaddress(@indirectbr_rewrite, %bb3),336                                                   ptr blockaddress(@indirectbr_rewrite, %bb4),337                                                   ptr blockaddress(@indirectbr_rewrite, %bb5),338                                                   ptr blockaddress(@indirectbr_rewrite, %bb6),339                                                   ptr blockaddress(@indirectbr_rewrite, %bb7),340                                                   ptr blockaddress(@indirectbr_rewrite, %bb8),341                                                   ptr blockaddress(@indirectbr_rewrite, %bb9)]342 343; Check that when retpolines are enabled for indirect branches the indirectbr344; instruction gets rewritten to use switch, and that in turn doesn't get lowered345; as a jump table.346define void @indirectbr_rewrite(ptr readonly %p, ptr %sink) #1 {347; X64-LABEL: indirectbr_rewrite:348; X64-NOT:     jmpq349; X86-LABEL: indirectbr_rewrite:350; X86-NOT:     jmpl351entry:352  %i0 = load i64, ptr %p353  %target.i0 = getelementptr [10 x ptr], ptr @indirectbr_rewrite.targets, i64 0, i64 %i0354  %target0 = load ptr, ptr %target.i0355  indirectbr ptr %target0, [label %bb1, label %bb3]356 357bb0:358  store volatile i64 0, ptr %sink359  br label %latch360 361bb1:362  store volatile i64 1, ptr %sink363  br label %latch364 365bb2:366  store volatile i64 2, ptr %sink367  br label %latch368 369bb3:370  store volatile i64 3, ptr %sink371  br label %latch372 373bb4:374  store volatile i64 4, ptr %sink375  br label %latch376 377bb5:378  store volatile i64 5, ptr %sink379  br label %latch380 381bb6:382  store volatile i64 6, ptr %sink383  br label %latch384 385bb7:386  store volatile i64 7, ptr %sink387  br label %latch388 389bb8:390  store volatile i64 8, ptr %sink391  br label %latch392 393bb9:394  store volatile i64 9, ptr %sink395  br label %latch396 397latch:398  %i.next = load i64, ptr %p399  %target.i.next = getelementptr [10 x ptr], ptr @indirectbr_rewrite.targets, i64 0, i64 %i.next400  %target.next = load ptr, ptr %target.i.next401  ; Potentially hit a full 10 successors here so that even if we rewrite as402  ; a switch it will try to be lowered with a jump table.403  indirectbr ptr %target.next, [label %bb0,404                                label %bb1,405                                label %bb2,406                                label %bb3,407                                label %bb4,408                                label %bb5,409                                label %bb6,410                                label %bb7,411                                label %bb8,412                                label %bb9]413}414 415; Lastly check that the necessary thunks were emitted.416;417; X64-LABEL:         .section        .text.__llvm_retpoline_r11,{{.*}},__llvm_retpoline_r11,comdat418; X64-NEXT:          .hidden __llvm_retpoline_r11419; X64-NEXT:          .weak   __llvm_retpoline_r11420; X64:       __llvm_retpoline_r11:421; X64-NEXT:  # {{.*}}                                # %entry422; X64-NEXT:          callq   [[CALL_TARGET:.*]]423; X64-NEXT:  [[CAPTURE_SPEC:.*]]:                    # Block address taken424; X64-NEXT:                                          # %entry425; X64-NEXT:                                          # =>This Inner Loop Header: Depth=1426; X64-NEXT:          pause427; X64-NEXT:          lfence428; X64-NEXT:          jmp     [[CAPTURE_SPEC]]429; X64-NEXT:          .p2align        4430; X64-NEXT:  {{.*}}                                  # Block address taken431; X64-NEXT:                                          # %entry432; X64-NEXT:  [[CALL_TARGET]]:433; X64-NEXT:          movq    %r11, (%rsp)434; X64-NEXT:          retq435;436; X86-LABEL:         .section        .text.__llvm_retpoline_eax,{{.*}},__llvm_retpoline_eax,comdat437; X86-NEXT:          .hidden __llvm_retpoline_eax438; X86-NEXT:          .weak   __llvm_retpoline_eax439; X86:       __llvm_retpoline_eax:440; X86-NEXT:  # {{.*}}                                # %entry441; X86-NEXT:          calll   [[CALL_TARGET:.*]]442; X86-NEXT:  [[CAPTURE_SPEC:.*]]:                    # Block address taken443; X86-NEXT:                                          # %entry444; X86-NEXT:                                          # =>This Inner Loop Header: Depth=1445; X86-NEXT:          pause446; X86-NEXT:          lfence447; X86-NEXT:          jmp     [[CAPTURE_SPEC]]448; X86-NEXT:          .p2align        4449; X86-NEXT:  {{.*}}                                  # Block address taken450; X86-NEXT:                                          # %entry451; X86-NEXT:  [[CALL_TARGET]]:452; X86-NEXT:          movl    %eax, (%esp)453; X86-NEXT:          retl454;455; X86-LABEL:         .section        .text.__llvm_retpoline_ecx,{{.*}},__llvm_retpoline_ecx,comdat456; X86-NEXT:          .hidden __llvm_retpoline_ecx457; X86-NEXT:          .weak   __llvm_retpoline_ecx458; X86:       __llvm_retpoline_ecx:459; X86-NEXT:  # {{.*}}                                # %entry460; X86-NEXT:          calll   [[CALL_TARGET:.*]]461; X86-NEXT:  [[CAPTURE_SPEC:.*]]:                    # Block address taken462; X86-NEXT:                                          # %entry463; X86-NEXT:                                          # =>This Inner Loop Header: Depth=1464; X86-NEXT:          pause465; X86-NEXT:          lfence466; X86-NEXT:          jmp     [[CAPTURE_SPEC]]467; X86-NEXT:          .p2align        4468; X86-NEXT:  {{.*}}                                  # Block address taken469; X86-NEXT:                                          # %entry470; X86-NEXT:  [[CALL_TARGET]]:471; X86-NEXT:          movl    %ecx, (%esp)472; X86-NEXT:          retl473;474; X86-LABEL:         .section        .text.__llvm_retpoline_edx,{{.*}},__llvm_retpoline_edx,comdat475; X86-NEXT:          .hidden __llvm_retpoline_edx476; X86-NEXT:          .weak   __llvm_retpoline_edx477; X86:       __llvm_retpoline_edx:478; X86-NEXT:  # {{.*}}                                # %entry479; X86-NEXT:          calll   [[CALL_TARGET:.*]]480; X86-NEXT:  [[CAPTURE_SPEC:.*]]:                    # Block address taken481; X86-NEXT:                                          # %entry482; X86-NEXT:                                          # =>This Inner Loop Header: Depth=1483; X86-NEXT:          pause484; X86-NEXT:          lfence485; X86-NEXT:          jmp     [[CAPTURE_SPEC]]486; X86-NEXT:          .p2align        4487; X86-NEXT:  {{.*}}                                  # Block address taken488; X86-NEXT:                                          # %entry489; X86-NEXT:  [[CALL_TARGET]]:490; X86-NEXT:          movl    %edx, (%esp)491; X86-NEXT:          retl492;493; X86-LABEL:         .section        .text.__llvm_retpoline_edi,{{.*}},__llvm_retpoline_edi,comdat494; X86-NEXT:          .hidden __llvm_retpoline_edi495; X86-NEXT:          .weak   __llvm_retpoline_edi496; X86:       __llvm_retpoline_edi:497; X86-NEXT:  # {{.*}}                                # %entry498; X86-NEXT:          calll   [[CALL_TARGET:.*]]499; X86-NEXT:  [[CAPTURE_SPEC:.*]]:                    # Block address taken500; X86-NEXT:                                          # %entry501; X86-NEXT:                                          # =>This Inner Loop Header: Depth=1502; X86-NEXT:          pause503; X86-NEXT:          lfence504; X86-NEXT:          jmp     [[CAPTURE_SPEC]]505; X86-NEXT:          .p2align        4506; X86-NEXT:  {{.*}}                                  # Block address taken507; X86-NEXT:                                          # %entry508; X86-NEXT:  [[CALL_TARGET]]:509; X86-NEXT:          movl    %edi, (%esp)510; X86-NEXT:          retl511 512 513attributes #0 = { "target-features"="+retpoline-indirect-calls" }514attributes #1 = { "target-features"="+retpoline-indirect-calls,+retpoline-indirect-branches" }515attributes #2 = { nonlazybind }516