Home | History | Annotate | Download | only in X86
      1 ; RUN: llc < %s -mtriple=x86_64-pc-win32 | FileCheck %s --check-prefix=CHECK --check-prefix=PUSHF
      2 ; RUN: llc < %s -mtriple=x86_64-pc-win32 -mattr=+sahf | FileCheck %s --check-prefix=SAHF
      3 
      4 define i32 @f1(i32 %p1, i32 %p2, i32 %p3, i32 %p4, i32 %p5) "no-frame-pointer-elim"="true" {
      5   ; CHECK-LABEL: f1:
      6   ; CHECK:       movl    48(%rbp), %eax
      7   ret i32 %p5
      8 }
      9 
     10 define void @f2(i32 %p, ...) "no-frame-pointer-elim"="true" {
     11   ; CHECK-LABEL: f2:
     12   ; CHECK:      .seh_stackalloc 8
     13   ; CHECK:      movq    %rsp, %rbp
     14   ; CHECK:      .seh_setframe 5, 0
     15   ; CHECK:      movq    %rdx, 32(%rbp)
     16   ; CHECK:      leaq    32(%rbp), %rax
     17   %ap = alloca i8, align 8
     18   call void @llvm.va_start(i8* %ap)
     19   ret void
     20 }
     21 
     22 define i8* @f3() "no-frame-pointer-elim"="true" {
     23   ; CHECK-LABEL: f3:
     24   ; CHECK:      movq    %rsp, %rbp
     25   ; CHECK:      .seh_setframe 5, 0
     26   ; CHECK:      movq    8(%rbp), %rax
     27   %ra = call i8* @llvm.returnaddress(i32 0)
     28   ret i8* %ra
     29 }
     30 
     31 define i8* @f4() "no-frame-pointer-elim"="true" {
     32   ; CHECK-LABEL: f4:
     33   ; CHECK:      pushq   %rbp
     34   ; CHECK:      .seh_pushreg 5
     35   ; CHECK:      subq    $304, %rsp
     36   ; CHECK:      .seh_stackalloc 304
     37   ; CHECK:      leaq    128(%rsp), %rbp
     38   ; CHECK:      .seh_setframe 5, 128
     39   ; CHECK:      .seh_endprologue
     40   ; CHECK:      movq    184(%rbp), %rax
     41   alloca [300 x i8]
     42   %ra = call i8* @llvm.returnaddress(i32 0)
     43   ret i8* %ra
     44 }
     45 
     46 declare void @external(i8*)
     47 
     48 define void @f5() "no-frame-pointer-elim"="true" {
     49   ; CHECK-LABEL: f5:
     50   ; CHECK:      subq    $336, %rsp
     51   ; CHECK:      .seh_stackalloc 336
     52   ; CHECK:      leaq    128(%rsp), %rbp
     53   ; CHECK:      .seh_setframe 5, 128
     54   ; CHECK:      leaq    -92(%rbp), %rcx
     55   ; CHECK:      callq   external
     56   %a = alloca [300 x i8]
     57   %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
     58   call void @external(i8* %gep)
     59   ret void
     60 }
     61 
     62 define void @f6(i32 %p, ...) "no-frame-pointer-elim"="true" {
     63   ; CHECK-LABEL: f6:
     64   ; CHECK:      subq    $336, %rsp
     65   ; CHECK:      .seh_stackalloc 336
     66   ; CHECK:      leaq    128(%rsp), %rbp
     67   ; CHECK:      .seh_setframe 5, 128
     68   ; CHECK:      leaq    -92(%rbp), %rcx
     69   ; CHECK:      callq   external
     70   %a = alloca [300 x i8]
     71   %gep = getelementptr [300 x i8], [300 x i8]* %a, i32 0, i32 0
     72   call void @external(i8* %gep)
     73   ret void
     74 }
     75 
     76 define i32 @f7(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
     77   ; CHECK-LABEL: f7:
     78   ; CHECK:      pushq   %rbp
     79   ; CHECK:      .seh_pushreg 5
     80   ; CHECK:      subq    $304, %rsp
     81   ; CHECK:      .seh_stackalloc 304
     82   ; CHECK:      leaq    128(%rsp), %rbp
     83   ; CHECK:      .seh_setframe 5, 128
     84   ; CHECK:      andq    $-64, %rsp
     85   ; CHECK:      movl    224(%rbp), %eax
     86   ; CHECK:      leaq    176(%rbp), %rsp
     87   alloca [300 x i8], align 64
     88   ret i32 %e
     89 }
     90 
     91 define i32 @f8(i32 %a, i32 %b, i32 %c, i32 %d, i32 %e) "no-frame-pointer-elim"="true" {
     92   ; CHECK-LABEL: f8:
     93   ; CHECK:        subq    $352, %rsp
     94   ; CHECK:        .seh_stackalloc 352
     95   ; CHECK:        leaq    128(%rsp), %rbp
     96   ; CHECK:        .seh_setframe 5, 128
     97 
     98   %alloca = alloca [300 x i8], align 64
     99   ; CHECK:        andq    $-64, %rsp
    100   ; CHECK:        movq    %rsp, %rbx
    101 
    102   alloca i32, i32 %a
    103   ; CHECK:        movl    %ecx, %eax
    104   ; CHECK:        leaq    15(,%rax,4), %rcx
    105   ; CHECK:        movabsq $34359738352, %rax
    106   ; CHECK:        andq    %rcx, %rax
    107   ; CHECK:        callq   __chkstk
    108   ; CHECK:        subq    %rax, %rsp
    109 
    110   %gep = getelementptr [300 x i8], [300 x i8]* %alloca, i32 0, i32 0
    111   call void @external(i8* %gep)
    112   ; CHECK:        subq    $32, %rsp
    113   ; CHECK:        leaq    (%rbx), %rcx
    114   ; CHECK:        callq   external
    115   ; CHECK:        addq    $32, %rsp
    116 
    117   ret i32 %e
    118   ; CHECK:        movl    %esi, %eax
    119   ; CHECK:        leaq    224(%rbp), %rsp
    120 }
    121 
    122 define i64 @f9() {
    123 entry:
    124   ; CHECK-LABEL: f9:
    125   ; CHECK:      pushq   %rbp
    126   ; CHECK:      .seh_pushreg 5
    127   ; CHECK-NEXT: movq    %rsp, %rbp
    128   ; CHECK:      .seh_setframe 5, 0
    129   ; CHECK:      .seh_endprologue
    130 
    131   %call = call i64 @llvm.x86.flags.read.u64()
    132   ; CHECK-NEXT: pushfq
    133   ; CHECK-NEXT: popq    %rax
    134 
    135   ret i64 %call
    136   ; CHECK-NEXT: popq    %rbp
    137   ; CHECK-NEXT: retq
    138 }
    139 
    140 declare i64 @dummy()
    141 
    142 define i64 @f10(i64* %foo, i64 %bar, i64 %baz) {
    143   ; CHECK-LABEL: f10:
    144   ; CHECK:      pushq   %rbp
    145   ; CHECK:      .seh_pushreg 5
    146   ; CHECK:      pushq   %rsi
    147   ; CHECK:      .seh_pushreg 6
    148   ; CHECK:      pushq   %rdi
    149   ; CHECK:      .seh_pushreg 7
    150   ; CHECK:      subq    $32, %rsp
    151   ; CHECK:      .seh_stackalloc 32
    152   ; CHECK:      leaq    32(%rsp), %rbp
    153   ; CHECK:      .seh_setframe 5, 32
    154   ; CHECK:      .seh_endprologue
    155 
    156   %cx = cmpxchg i64* %foo, i64 %bar, i64 %baz seq_cst seq_cst
    157   ; PUSHF:      lock cmpxchgq
    158   ; PUSHF-NEXT: pushfq
    159   ; PUSHF-NEXT: popq %[[REG:.*]]
    160   ; SAHF:       lock cmpxchgq
    161   ; SAHF-NEXT:  seto    %al
    162   ; SAHF-NEXT:  lahf
    163 
    164   %v = extractvalue { i64, i1 } %cx, 0
    165   %p = extractvalue { i64, i1 } %cx, 1
    166 
    167   %call = call i64 @dummy()
    168   ; PUSHF:      callq dummy
    169   ; PUSHF-NEXT: pushq %[[REG]]
    170   ; PUSHF-NEXT: popfq
    171   ; SAHF:       callq dummy
    172   ; SAHF-NEXT:  pushq
    173   ; SAHF:       addb $127, %al
    174   ; SAHF-NEXT:  sahf
    175   ; SAHF-NEXT:  popq
    176 
    177   %sel = select i1 %p, i64 %call, i64 %bar
    178   ; CHECK-NEXT: cmovneq
    179 
    180   ret i64 %sel
    181   ; CHECK-NEXT: addq    $32, %rsp
    182   ; CHECK-NEXT: popq    %rdi
    183   ; CHECK-NEXT: popq    %rsi
    184   ; CHECK-NEXT: popq    %rbp
    185 }
    186 
    187 declare i8* @llvm.returnaddress(i32) nounwind readnone
    188 declare i64 @llvm.x86.flags.read.u64()
    189 
    190 declare void @llvm.va_start(i8*) nounwind
    191