1; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
2; RUN: llc -verify-machineinstrs -O3 -enable-implicit-null-checks -mcpu=skylake -x86-align-branch-boundary=32 -x86-align-branch=call+jmp+indirect+ret+jcc < %s | FileCheck %s
3
4;; The tests in this file check that various constructs which need to disable
5;; prefix and/or nop padding do so in the right places.  However, since we
6;; don't yet have assembler syntax for this, they're only able to check
7;; comments and must hope the assembler does the right thing.
8
9target datalayout = "e-i64:64-f80:128-n8:16:32:64-S128"
10target triple = "x86_64-pc-linux-gnu"
11
12; If we have autopadding enabled, make sure the label isn't separated from
13; the mov.
14define i32 @implicit_null_check(i32* %x) {
15; CHECK-LABEL: implicit_null_check:
16; CHECK:       # %bb.0: # %entry
17; CHECK-NEXT:    #noautopadding
18; CHECK-NEXT:  .Ltmp0:
19; CHECK-NEXT:    movl (%rdi), %eax # on-fault: .LBB0_1
20; CHECK-NEXT:    #autopadding
21; CHECK-NEXT:  # %bb.2: # %not_null
22; CHECK-NEXT:    retq
23; CHECK-NEXT:  .LBB0_1: # %is_null
24; CHECK-NEXT:    movl $42, %eax
25; CHECK-NEXT:    retq
26
27 entry:
28  %c = icmp eq i32* %x, null
29  br i1 %c, label %is_null, label %not_null, !make.implicit !{}
30
31 is_null:
32  ret i32 42
33
34 not_null:
35  %t = load atomic i32, i32* %x unordered, align 4
36  ret i32 %t
37}
38
39; Label must bind to call before
40define void @test_statepoint(i32 addrspace(1)* %ptr) gc "statepoint-example" {
41; CHECK-LABEL: test_statepoint:
42; CHECK:       # %bb.0: # %entry
43; CHECK-NEXT:    pushq %rax
44; CHECK-NEXT:    .cfi_def_cfa_offset 16
45; CHECK-NEXT:    #noautopadding
46; CHECK-NEXT:    callq return_i1@PLT
47; CHECK-NEXT:  .Ltmp1:
48; CHECK-NEXT:    #autopadding
49; CHECK-NEXT:    popq %rax
50; CHECK-NEXT:    .cfi_def_cfa_offset 8
51; CHECK-NEXT:    retq
52entry:
53  call token (i64, i32, i1 ()*, i32, i32, ...) @llvm.experimental.gc.statepoint.p0f_i1f(i64 0, i32 0, i1 ()* @return_i1, i32 0, i32 0, i32 0, i32 0)
54  ret void
55}
56
57declare zeroext i1 @return_i1()
58declare token @llvm.experimental.gc.statepoint.p0f_i1f(i64, i32, i1 ()*, i32, i32, ...)
59
60
61; Label must bind to following nop sequence
62define void @patchpoint(i64 %a, i64 %b) {
63; CHECK-LABEL: patchpoint:
64; CHECK:       # %bb.0: # %entry
65; CHECK-NEXT:    pushq %rbp
66; CHECK-NEXT:    .cfi_def_cfa_offset 16
67; CHECK-NEXT:    .cfi_offset %rbp, -16
68; CHECK-NEXT:    movq %rsp, %rbp
69; CHECK-NEXT:    .cfi_def_cfa_register %rbp
70; CHECK-NEXT:    #noautopadding
71; CHECK-NEXT:  .Ltmp2:
72; CHECK-NEXT:    .byte 102
73; CHECK-NEXT:    .byte 102
74; CHECK-NEXT:    .byte 102
75; CHECK-NEXT:    .byte 102
76; CHECK-NEXT:    .byte 102
77; CHECK-NEXT:    nopw %cs:512(%rax,%rax)
78; CHECK-NEXT:    #autopadding
79; CHECK-NEXT:    popq %rbp
80; CHECK-NEXT:    .cfi_def_cfa %rsp, 8
81; CHECK-NEXT:    retq
82entry:
83  call void (i64, i32, i8*, i32, ...) @llvm.experimental.patchpoint.void(i64 4, i32 15, i8* null, i32 0, i64 %a, i64 %b)
84  ret void
85}
86
87
88declare void @llvm.experimental.stackmap(i64, i32, ...)
89declare void @llvm.experimental.patchpoint.void(i64, i32, i8*, i32, ...)
90