Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt < %s -inline -S | FileCheck %s
      2 target datalayout = "E-p:64:64:64-a0:0:8-f32:32:32-f64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-v64:64:64-v128:128:128"
      3 
      4 define i32 @noattr_callee(i32 %i) {
      5   ret i32 %i
      6 }
      7 
      8 define i32 @sanitize_address_callee(i32 %i) sanitize_address {
      9   ret i32 %i
     10 }
     11 
     12 define i32 @sanitize_thread_callee(i32 %i) sanitize_thread {
     13   ret i32 %i
     14 }
     15 
     16 define i32 @sanitize_memory_callee(i32 %i) sanitize_memory {
     17   ret i32 %i
     18 }
     19 
     20 define i32 @safestack_callee(i32 %i) safestack {
     21   ret i32 %i
     22 }
     23 
     24 define i32 @alwaysinline_callee(i32 %i) alwaysinline {
     25   ret i32 %i
     26 }
     27 
     28 define i32 @alwaysinline_sanitize_address_callee(i32 %i) alwaysinline sanitize_address {
     29   ret i32 %i
     30 }
     31 
     32 define i32 @alwaysinline_sanitize_thread_callee(i32 %i) alwaysinline sanitize_thread {
     33   ret i32 %i
     34 }
     35 
     36 define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_memory {
     37   ret i32 %i
     38 }
     39 
     40 define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack {
     41   ret i32 %i
     42 }
     43 
     44 
     45 ; Check that:
     46 ;  * noattr callee is inlined into noattr caller,
     47 ;  * sanitize_(address|memory|thread) callee is not inlined into noattr caller,
     48 ;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
     49 
     50 define i32 @test_no_sanitize_address(i32 %arg) {
     51   %x1 = call i32 @noattr_callee(i32 %arg)
     52   %x2 = call i32 @sanitize_address_callee(i32 %x1)
     53   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     54   %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
     55   ret i32 %x4
     56 ; CHECK-LABEL: @test_no_sanitize_address(
     57 ; CHECK-NEXT: @sanitize_address_callee
     58 ; CHECK-NEXT: ret i32
     59 }
     60 
     61 define i32 @test_no_sanitize_memory(i32 %arg) {
     62   %x1 = call i32 @noattr_callee(i32 %arg)
     63   %x2 = call i32 @sanitize_memory_callee(i32 %x1)
     64   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     65   %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
     66   ret i32 %x4
     67 ; CHECK-LABEL: @test_no_sanitize_memory(
     68 ; CHECK-NEXT: @sanitize_memory_callee
     69 ; CHECK-NEXT: ret i32
     70 }
     71 
     72 define i32 @test_no_sanitize_thread(i32 %arg) {
     73   %x1 = call i32 @noattr_callee(i32 %arg)
     74   %x2 = call i32 @sanitize_thread_callee(i32 %x1)
     75   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     76   %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
     77   ret i32 %x4
     78 ; CHECK-LABEL: @test_no_sanitize_thread(
     79 ; CHECK-NEXT: @sanitize_thread_callee
     80 ; CHECK-NEXT: ret i32
     81 }
     82 
     83 
     84 ; Check that:
     85 ;  * noattr callee is not inlined into sanitize_(address|memory|thread) caller,
     86 ;  * sanitize_(address|memory|thread) callee is inlined into the caller with the same attribute,
     87 ;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
     88 
     89 define i32 @test_sanitize_address(i32 %arg) sanitize_address {
     90   %x1 = call i32 @noattr_callee(i32 %arg)
     91   %x2 = call i32 @sanitize_address_callee(i32 %x1)
     92   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     93   %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
     94   ret i32 %x4
     95 ; CHECK-LABEL: @test_sanitize_address(
     96 ; CHECK-NEXT: @noattr_callee
     97 ; CHECK-NEXT: ret i32
     98 }
     99 
    100 define i32 @test_sanitize_memory(i32 %arg) sanitize_memory {
    101   %x1 = call i32 @noattr_callee(i32 %arg)
    102   %x2 = call i32 @sanitize_memory_callee(i32 %x1)
    103   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    104   %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
    105   ret i32 %x4
    106 ; CHECK-LABEL: @test_sanitize_memory(
    107 ; CHECK-NEXT: @noattr_callee
    108 ; CHECK-NEXT: ret i32
    109 }
    110 
    111 define i32 @test_sanitize_thread(i32 %arg) sanitize_thread {
    112   %x1 = call i32 @noattr_callee(i32 %arg)
    113   %x2 = call i32 @sanitize_thread_callee(i32 %x1)
    114   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    115   %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
    116   ret i32 %x4
    117 ; CHECK-LABEL: @test_sanitize_thread(
    118 ; CHECK-NEXT: @noattr_callee
    119 ; CHECK-NEXT: ret i32
    120 }
    121 
    122 define i32 @test_safestack(i32 %arg) safestack {
    123   %x1 = call i32 @noattr_callee(i32 %arg)
    124   %x2 = call i32 @safestack_callee(i32 %x1)
    125   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    126   %x4 = call i32 @alwaysinline_safestack_callee(i32 %x3)
    127   ret i32 %x4
    128 ; CHECK-LABEL: @test_safestack(
    129 ; CHECK-NEXT: @noattr_callee
    130 ; CHECK-NEXT: ret i32
    131 }
    132 
    133 ; Check that a function doesn't get inlined if target-cpu strings don't match
    134 ; exactly.
    135 define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" {
    136   ret i32 %i
    137 }
    138 
    139 define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" {
    140   %1 = call i32 @test_target_cpu_callee0(i32 %i)
    141   ret i32 %1
    142 ; CHECK-LABEL: @test_target_cpu0(
    143 ; CHECK-NOT: @test_target_cpu_callee0
    144 }
    145 
    146 define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" {
    147   ret i32 %i
    148 }
    149 
    150 define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" {
    151   %1 = call i32 @test_target_cpu_callee1(i32 %i)
    152   ret i32 %1
    153 ; CHECK-LABEL: @test_target_cpu1(
    154 ; CHECK-NEXT: @test_target_cpu_callee1
    155 ; CHECK-NEXT: ret i32
    156 }
    157 
    158 ; Check that a function doesn't get inlined if target-features strings don't
    159 ; match exactly.
    160 define i32 @test_target_features_callee0(i32 %i)  "target-features"="+sse4.2" {
    161   ret i32 %i
    162 }
    163 
    164 define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" {
    165   %1 = call i32 @test_target_features_callee0(i32 %i)
    166   ret i32 %1
    167 ; CHECK-LABEL: @test_target_features0(
    168 ; CHECK-NOT: @test_target_features_callee0
    169 }
    170 
    171 define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" {
    172   ret i32 %i
    173 }
    174 
    175 define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" {
    176   %1 = call i32 @test_target_features_callee1(i32 %i)
    177   ret i32 %1
    178 ; CHECK-LABEL: @test_target_features1(
    179 ; CHECK-NEXT: @test_target_features_callee1
    180 ; CHECK-NEXT: ret i32
    181 }
    182 
    183 define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" {
    184   ret i32 %i
    185 ; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] {
    186 ; CHECK-NEXT: ret i32
    187 }
    188 
    189 define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" {
    190   ret i32 %i
    191 ; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] {
    192 ; CHECK-NEXT: ret i32
    193 }
    194 
    195 define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" {
    196   %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
    197   ret i32 %1
    198 ; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] {
    199 ; CHECK-NEXT: ret i32
    200 }
    201 
    202 define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" {
    203   %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
    204   ret i32 %1
    205 ; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] {
    206 ; CHECK-NEXT: ret i32
    207 }
    208 
    209 define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" {
    210   %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
    211   ret i32 %1
    212 ; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] {
    213 ; CHECK-NEXT: ret i32
    214 }
    215 
    216 define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" {
    217   %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
    218   ret i32 %1
    219 ; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] {
    220 ; CHECK-NEXT: ret i32
    221 }
    222 
    223 define i32 @no-implicit-float_callee0(i32 %i) {
    224   ret i32 %i
    225 ; CHECK: @no-implicit-float_callee0(i32 %i) {
    226 ; CHECK-NEXT: ret i32
    227 }
    228 
    229 define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat {
    230   ret i32 %i
    231 ; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] {
    232 ; CHECK-NEXT: ret i32
    233 }
    234 
    235 define i32 @test_no-implicit-float0(i32 %i) {
    236   %1 = call i32 @no-implicit-float_callee0(i32 %i)
    237   ret i32 %1
    238 ; CHECK: @test_no-implicit-float0(i32 %i) {
    239 ; CHECK-NEXT: ret i32
    240 }
    241 
    242 define i32 @test_no-implicit-float1(i32 %i) {
    243   %1 = call i32 @no-implicit-float_callee1(i32 %i)
    244   ret i32 %1
    245 ; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] {
    246 ; CHECK-NEXT: ret i32
    247 }
    248 
    249 define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat {
    250   %1 = call i32 @no-implicit-float_callee0(i32 %i)
    251   ret i32 %1
    252 ; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] {
    253 ; CHECK-NEXT: ret i32
    254 }
    255 
    256 define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat {
    257   %1 = call i32 @no-implicit-float_callee1(i32 %i)
    258   ret i32 %1
    259 ; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] {
    260 ; CHECK-NEXT: ret i32
    261 }
    262 
    263 ; Check that no-jump-tables flag propagates from inlined callee to caller 
    264 
    265 define i32 @no-use-jump-tables_callee0(i32 %i) {
    266   ret i32 %i
    267 ; CHECK: @no-use-jump-tables_callee0(i32 %i) {
    268 ; CHECK-NEXT: ret i32
    269 }
    270 
    271 define i32 @no-use-jump-tables_callee1(i32 %i) "no-jump-tables"="true" {
    272   ret i32 %i
    273 ; CHECK: @no-use-jump-tables_callee1(i32 %i) [[NOUSEJUMPTABLES:#[0-9]+]] {
    274 ; CHECK-NEXT: ret i32
    275 }
    276 
    277 define i32 @test_no-use-jump-tables0(i32 %i) {
    278   %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
    279   ret i32 %1
    280 ; CHECK: @test_no-use-jump-tables0(i32 %i) {
    281 ; CHECK-NEXT: ret i32
    282 }
    283 
    284 define i32 @test_no-use-jump-tables1(i32 %i) {
    285   %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
    286   ret i32 %1
    287 ; CHECK: @test_no-use-jump-tables1(i32 %i) [[NOUSEJUMPTABLES]] {
    288 ; CHECK-NEXT: ret i32
    289 }
    290 
    291 define i32 @test_no-use-jump-tables2(i32 %i) "no-jump-tables"="true" {
    292   %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
    293   ret i32 %1
    294 ; CHECK: @test_no-use-jump-tables2(i32 %i) [[NOUSEJUMPTABLES]] {
    295 ; CHECK-NEXT: ret i32
    296 }
    297 
    298 define i32 @test_no-use-jump-tables3(i32 %i) "no-jump-tables"="true" {
    299   %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
    300   ret i32 %1
    301 ; CHECK: @test_no-use-jump-tables3(i32 %i) [[NOUSEJUMPTABLES]] {
    302 ; CHECK-NEXT: ret i32
    303 }
    304 
    305 ; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" }
    306 ; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" }
    307 ; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat }
    308 ; CHECK: attributes [[NOUSEJUMPTABLES]] = { "no-jump-tables"="true" }