Home | History | Annotate | Download | only in X86
      1 ; RUN: llc -mtriple=x86_64-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86_64
      2 ; RUN: llc -mtriple=i386-unknown-unknown < %s | FileCheck %s --check-prefix=ALL --check-prefix=X86
      3 ; RUN: llc -mtriple i386-windows-gnu -exception-model sjlj < %s | FileCheck %s --check-prefix=SJLJ
      4 
      5 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
      6 ;; Test1
      7 ;; -----
      8 ;; Checks ENDBR insertion in case of switch case statement.
      9 ;; Also since the function is not internal, make sure that endbr32/64 was 
     10 ;; added at the beginning of the function.
     11 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     12 
     13 define i8 @test1(){
     14 ; ALL-LABEL:   test1
     15 ; X86_64:      endbr64
     16 ; X86:         endbr32
     17 ; ALL:         jmp{{q|l}} *
     18 ; ALL:         .LBB0_1:
     19 ; X86_64-NEXT: endbr64
     20 ; X86-NEXT:    endbr32
     21 ; ALL:         .LBB0_2:
     22 ; X86_64-NEXT: endbr64
     23 ; X86-NEXT:    endbr32
     24 entry:
     25   %0 = select i1 undef, i8* blockaddress(@test1, %bb), i8* blockaddress(@test1, %bb6) ; <i8*> [#uses=1]
     26   indirectbr i8* %0, [label %bb, label %bb6]
     27 
     28 bb:                                               ; preds = %entry
     29   ret i8 1
     30 
     31 bb6:                                              ; preds = %entry
     32   ret i8 2
     33 }
     34 
     35 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     36 ;; Test2
     37 ;; -----
     38 ;; Checks NOTRACK insertion in case of switch case statement.
     39 ;; Check that there is no ENDBR insertion in the following case statements.
     40 ;; Also since the function is not internal, ENDBR instruction should be
     41 ;; added to its first basic block.
     42 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     43 
     44 define i32 @test2(i32 %a) {
     45 ; ALL-LABEL:   test2
     46 ; X86_64:      endbr64
     47 ; X86:         endbr32
     48 ; ALL:         notrack jmp{{q|l}} *
     49 ; X86_64-NOT:      endbr64
     50 ; X86-NOT:         endbr32
     51 entry:
     52   %retval = alloca i32, align 4
     53   %a.addr = alloca i32, align 4
     54   store i32 %a, i32* %a.addr, align 4
     55   %0 = load i32, i32* %a.addr, align 4
     56   switch i32 %0, label %sw.default [
     57     i32 0, label %sw.bb
     58     i32 1, label %sw.bb1
     59     i32 2, label %sw.bb2
     60     i32 3, label %sw.bb3
     61     i32 4, label %sw.bb4
     62   ]
     63 
     64 sw.bb:                                            ; preds = %entry
     65   store i32 5, i32* %retval, align 4
     66   br label %return
     67 
     68 sw.bb1:                                           ; preds = %entry
     69   store i32 7, i32* %retval, align 4
     70   br label %return
     71 
     72 sw.bb2:                                           ; preds = %entry
     73   store i32 2, i32* %retval, align 4
     74   br label %return
     75 
     76 sw.bb3:                                           ; preds = %entry
     77   store i32 32, i32* %retval, align 4
     78   br label %return
     79 
     80 sw.bb4:                                           ; preds = %entry
     81   store i32 73, i32* %retval, align 4
     82   br label %return
     83 
     84 sw.default:                                       ; preds = %entry
     85   store i32 0, i32* %retval, align 4
     86   br label %return
     87 
     88 return:                                           ; preds = %sw.default, %sw.bb4, %sw.bb3, %sw.bb2, %sw.bb1, %sw.bb
     89   %1 = load i32, i32* %retval, align 4
     90   ret i32 %1
     91 }
     92 
     93 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
     94 ;; Test3
     95 ;; -----
     96 ;; Checks ENDBR insertion in case of indirect call instruction.
     97 ;; The new instruction should be added to the called function (test6)
     98 ;; although it is internal.
     99 ;; Also since the function is not internal, ENDBR instruction should be
    100 ;; added to its first basic block.
    101 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    102 
    103 define void @test3() {
    104 ; ALL-LABEL:   test3
    105 ; X86_64:      endbr64
    106 ; X86:         endbr32
    107 ; ALL:         call{{q|l}} *
    108 entry:
    109   %f = alloca i32 (...)*, align 8
    110   store i32 (...)* bitcast (i32 (i32)* @test6 to i32 (...)*), i32 (...)** %f, align 8
    111   %0 = load i32 (...)*, i32 (...)** %f, align 8
    112   %call = call i32 (...) %0()
    113   ret void
    114 }
    115 
    116 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    117 ;; Test4
    118 ;; -----
    119 ;; Checks ENDBR insertion in case of setjmp-like function calls.
    120 ;; Also since the function is not internal, ENDBR instruction should be
    121 ;; added to its first basic block.
    122 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    123 
    124 @buf = internal global [5 x i8*] zeroinitializer
    125 declare i8* @llvm.frameaddress(i32)
    126 declare i8* @llvm.stacksave()
    127 declare i32 @llvm.eh.sjlj.setjmp(i8*)
    128 
    129 define i32 @test4() {
    130 ; ALL-LABEL:   test4
    131 ; X86_64:      endbr64
    132 ; X86:         endbr32
    133 ; ALL:         .LBB3_3:
    134 ; X86_64-NEXT: endbr64
    135 ; X86-NEXT:    endbr32
    136   %fp = tail call i8* @llvm.frameaddress(i32 0)
    137   store i8* %fp, i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @buf, i64 0, i64 0), align 16
    138   %sp = tail call i8* @llvm.stacksave()
    139   store i8* %sp, i8** getelementptr inbounds ([5 x i8*], [5 x i8*]* @buf, i64 0, i64 2), align 16
    140   %r = tail call i32 @llvm.eh.sjlj.setjmp(i8* bitcast ([5 x i8*]* @buf to i8*))
    141   ret i32 %r
    142 }
    143 
    144 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    145 ;; Test5
    146 ;; -----
    147 ;; Checks ENDBR insertion in case of internal function.
    148 ;; Since the function is internal and its address was not taken,
    149 ;; make sure that endbr32/64 was not added at the beginning of the 
    150 ;; function.
    151 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    152 
    153 define internal i8 @test5(){
    154 ; ALL-LABEL:   test5
    155 ; X86_64-NOT:      endbr64
    156 ; X86-NOT:         endbr32
    157   ret i8 1
    158 }
    159 
    160 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    161 ;; Test6
    162 ;; -----
    163 ;; Checks ENDBR insertion in case of function that its was address taken.
    164 ;; Since the function's address was taken by test3() and despite being
    165 ;; internal, check for added endbr32/64 at the beginning of the function.
    166 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    167 
    168 define internal i32 @test6(i32 %a) {
    169 ; ALL-LABEL:   test6
    170 ; X86_64:      endbr64
    171 ; X86:         endbr32
    172   ret i32 1
    173 }
    174 
    175 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    176 ;; Test7
    177 ;; -----
    178 ;; Checks ENDBR insertion in case of non-intrenal function.
    179 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    180 
    181 define i32 @test7() {
    182 ; ALL-LABEL:   test7
    183 ; X86_64:      endbr64
    184 ; X86:         endbr32
    185   ret i32 1
    186 }
    187 
    188 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    189 ;; Test8
    190 ;; -----
    191 ;; Checks that NO TRACK prefix is not added for indirect jumps to a jump-
    192 ;; table that was created for SJLJ dispatch.
    193 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
    194 
    195 declare void @_Z20function_that_throwsv()
    196 declare i32 @__gxx_personality_sj0(...)
    197 declare i8* @__cxa_begin_catch(i8*)
    198 declare void @__cxa_end_catch()
    199 
    200 define void @test8() personality i8* bitcast (i32 (...)* @__gxx_personality_sj0 to i8*) {
    201 ;SJLJ-LABEL:    test8
    202 ;SJLJ-NOT:      ds
    203 entry:
    204   invoke void @_Z20function_that_throwsv()
    205           to label %try.cont unwind label %lpad
    206 
    207 lpad:
    208   %0 = landingpad { i8*, i32 }
    209           catch i8* null
    210   %1 = extractvalue { i8*, i32 } %0, 0
    211   %2 = tail call i8* @__cxa_begin_catch(i8* %1)
    212   tail call void @__cxa_end_catch()
    213   br label %try.cont
    214 
    215 try.cont:
    216   ret void
    217 }
    218 
    219 !llvm.module.flags = !{!0}
    220 
    221 !0 = !{i32 4, !"cf-protection-branch", i32 1}
    222