Home | History | Annotate | Download | only in Inline
      1 ; RUN: opt < %s -inline -S | FileCheck %s
      2 ; RUN: opt < %s -passes='cgscc(inline)' -S | FileCheck %s
      3 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"
      4 
      5 define i32 @noattr_callee(i32 %i) {
      6   ret i32 %i
      7 }
      8 
      9 define i32 @sanitize_address_callee(i32 %i) sanitize_address {
     10   ret i32 %i
     11 }
     12 
     13 define i32 @sanitize_hwaddress_callee(i32 %i) sanitize_hwaddress {
     14   ret i32 %i
     15 }
     16 
     17 define i32 @sanitize_thread_callee(i32 %i) sanitize_thread {
     18   ret i32 %i
     19 }
     20 
     21 define i32 @sanitize_memory_callee(i32 %i) sanitize_memory {
     22   ret i32 %i
     23 }
     24 
     25 define i32 @safestack_callee(i32 %i) safestack {
     26   ret i32 %i
     27 }
     28 
     29 define i32 @alwaysinline_callee(i32 %i) alwaysinline {
     30   ret i32 %i
     31 }
     32 
     33 define i32 @alwaysinline_sanitize_address_callee(i32 %i) alwaysinline sanitize_address {
     34   ret i32 %i
     35 }
     36 
     37 define i32 @alwaysinline_sanitize_hwaddress_callee(i32 %i) alwaysinline sanitize_hwaddress {
     38   ret i32 %i
     39 }
     40 
     41 define i32 @alwaysinline_sanitize_thread_callee(i32 %i) alwaysinline sanitize_thread {
     42   ret i32 %i
     43 }
     44 
     45 define i32 @alwaysinline_sanitize_memory_callee(i32 %i) alwaysinline sanitize_memory {
     46   ret i32 %i
     47 }
     48 
     49 define i32 @alwaysinline_safestack_callee(i32 %i) alwaysinline safestack {
     50   ret i32 %i
     51 }
     52 
     53 
     54 ; Check that:
     55 ;  * noattr callee is inlined into noattr caller,
     56 ;  * sanitize_(address|memory|thread) callee is not inlined into noattr caller,
     57 ;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
     58 
     59 define i32 @test_no_sanitize_address(i32 %arg) {
     60   %x1 = call i32 @noattr_callee(i32 %arg)
     61   %x2 = call i32 @sanitize_address_callee(i32 %x1)
     62   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     63   %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
     64   ret i32 %x4
     65 ; CHECK-LABEL: @test_no_sanitize_address(
     66 ; CHECK-NEXT: @sanitize_address_callee
     67 ; CHECK-NEXT: ret i32
     68 }
     69 
     70 define i32 @test_no_sanitize_hwaddress(i32 %arg) {
     71   %x1 = call i32 @noattr_callee(i32 %arg)
     72   %x2 = call i32 @sanitize_hwaddress_callee(i32 %x1)
     73   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     74   %x4 = call i32 @alwaysinline_sanitize_hwaddress_callee(i32 %x3)
     75   ret i32 %x4
     76 ; CHECK-LABEL: @test_no_sanitize_hwaddress(
     77 ; CHECK-NEXT: @sanitize_hwaddress_callee
     78 ; CHECK-NEXT: ret i32
     79 }
     80 
     81 define i32 @test_no_sanitize_memory(i32 %arg) {
     82   %x1 = call i32 @noattr_callee(i32 %arg)
     83   %x2 = call i32 @sanitize_memory_callee(i32 %x1)
     84   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     85   %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
     86   ret i32 %x4
     87 ; CHECK-LABEL: @test_no_sanitize_memory(
     88 ; CHECK-NEXT: @sanitize_memory_callee
     89 ; CHECK-NEXT: ret i32
     90 }
     91 
     92 define i32 @test_no_sanitize_thread(i32 %arg) {
     93   %x1 = call i32 @noattr_callee(i32 %arg)
     94   %x2 = call i32 @sanitize_thread_callee(i32 %x1)
     95   %x3 = call i32 @alwaysinline_callee(i32 %x2)
     96   %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
     97   ret i32 %x4
     98 ; CHECK-LABEL: @test_no_sanitize_thread(
     99 ; CHECK-NEXT: @sanitize_thread_callee
    100 ; CHECK-NEXT: ret i32
    101 }
    102 
    103 
    104 ; Check that:
    105 ;  * noattr callee is not inlined into sanitize_(address|memory|thread) caller,
    106 ;  * sanitize_(address|memory|thread) callee is inlined into the caller with the same attribute,
    107 ;  * alwaysinline callee is always inlined no matter what sanitize_* attributes are present.
    108 
    109 define i32 @test_sanitize_address(i32 %arg) sanitize_address {
    110   %x1 = call i32 @noattr_callee(i32 %arg)
    111   %x2 = call i32 @sanitize_address_callee(i32 %x1)
    112   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    113   %x4 = call i32 @alwaysinline_sanitize_address_callee(i32 %x3)
    114   ret i32 %x4
    115 ; CHECK-LABEL: @test_sanitize_address(
    116 ; CHECK-NEXT: @noattr_callee
    117 ; CHECK-NEXT: ret i32
    118 }
    119 
    120 define i32 @test_sanitize_hwaddress(i32 %arg) sanitize_hwaddress {
    121   %x1 = call i32 @noattr_callee(i32 %arg)
    122   %x2 = call i32 @sanitize_hwaddress_callee(i32 %x1)
    123   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    124   %x4 = call i32 @alwaysinline_sanitize_hwaddress_callee(i32 %x3)
    125   ret i32 %x4
    126 ; CHECK-LABEL: @test_sanitize_hwaddress(
    127 ; CHECK-NEXT: @noattr_callee
    128 ; CHECK-NEXT: ret i32
    129 }
    130 
    131 define i32 @test_sanitize_memory(i32 %arg) sanitize_memory {
    132   %x1 = call i32 @noattr_callee(i32 %arg)
    133   %x2 = call i32 @sanitize_memory_callee(i32 %x1)
    134   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    135   %x4 = call i32 @alwaysinline_sanitize_memory_callee(i32 %x3)
    136   ret i32 %x4
    137 ; CHECK-LABEL: @test_sanitize_memory(
    138 ; CHECK-NEXT: @noattr_callee
    139 ; CHECK-NEXT: ret i32
    140 }
    141 
    142 define i32 @test_sanitize_thread(i32 %arg) sanitize_thread {
    143   %x1 = call i32 @noattr_callee(i32 %arg)
    144   %x2 = call i32 @sanitize_thread_callee(i32 %x1)
    145   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    146   %x4 = call i32 @alwaysinline_sanitize_thread_callee(i32 %x3)
    147   ret i32 %x4
    148 ; CHECK-LABEL: @test_sanitize_thread(
    149 ; CHECK-NEXT: @noattr_callee
    150 ; CHECK-NEXT: ret i32
    151 }
    152 
    153 define i32 @test_safestack(i32 %arg) safestack {
    154   %x1 = call i32 @noattr_callee(i32 %arg)
    155   %x2 = call i32 @safestack_callee(i32 %x1)
    156   %x3 = call i32 @alwaysinline_callee(i32 %x2)
    157   %x4 = call i32 @alwaysinline_safestack_callee(i32 %x3)
    158   ret i32 %x4
    159 ; CHECK-LABEL: @test_safestack(
    160 ; CHECK-NEXT: @noattr_callee
    161 ; CHECK-NEXT: ret i32
    162 }
    163 
    164 ; Check that a function doesn't get inlined if target-cpu strings don't match
    165 ; exactly.
    166 define i32 @test_target_cpu_callee0(i32 %i) "target-cpu"="corei7" {
    167   ret i32 %i
    168 }
    169 
    170 define i32 @test_target_cpu0(i32 %i) "target-cpu"="corei7" {
    171   %1 = call i32 @test_target_cpu_callee0(i32 %i)
    172   ret i32 %1
    173 ; CHECK-LABEL: @test_target_cpu0(
    174 ; CHECK-NOT: @test_target_cpu_callee0
    175 }
    176 
    177 define i32 @test_target_cpu_callee1(i32 %i) "target-cpu"="x86-64" {
    178   ret i32 %i
    179 }
    180 
    181 define i32 @test_target_cpu1(i32 %i) "target-cpu"="corei7" {
    182   %1 = call i32 @test_target_cpu_callee1(i32 %i)
    183   ret i32 %1
    184 ; CHECK-LABEL: @test_target_cpu1(
    185 ; CHECK-NEXT: @test_target_cpu_callee1
    186 ; CHECK-NEXT: ret i32
    187 }
    188 
    189 ; Check that a function doesn't get inlined if target-features strings don't
    190 ; match exactly.
    191 define i32 @test_target_features_callee0(i32 %i)  "target-features"="+sse4.2" {
    192   ret i32 %i
    193 }
    194 
    195 define i32 @test_target_features0(i32 %i) "target-features"="+sse4.2" {
    196   %1 = call i32 @test_target_features_callee0(i32 %i)
    197   ret i32 %1
    198 ; CHECK-LABEL: @test_target_features0(
    199 ; CHECK-NOT: @test_target_features_callee0
    200 }
    201 
    202 define i32 @test_target_features_callee1(i32 %i) "target-features"="+avx2" {
    203   ret i32 %i
    204 }
    205 
    206 define i32 @test_target_features1(i32 %i) "target-features"="+sse4.2" {
    207   %1 = call i32 @test_target_features_callee1(i32 %i)
    208   ret i32 %1
    209 ; CHECK-LABEL: @test_target_features1(
    210 ; CHECK-NEXT: @test_target_features_callee1
    211 ; CHECK-NEXT: ret i32
    212 }
    213 
    214 define i32 @less-precise-fpmad_callee0(i32 %i) "less-precise-fpmad"="false" {
    215   ret i32 %i
    216 ; CHECK: @less-precise-fpmad_callee0(i32 %i) [[FPMAD_FALSE:#[0-9]+]] {
    217 ; CHECK-NEXT: ret i32
    218 }
    219 
    220 define i32 @less-precise-fpmad_callee1(i32 %i) "less-precise-fpmad"="true" {
    221   ret i32 %i
    222 ; CHECK: @less-precise-fpmad_callee1(i32 %i) [[FPMAD_TRUE:#[0-9]+]] {
    223 ; CHECK-NEXT: ret i32
    224 }
    225 
    226 define i32 @test_less-precise-fpmad0(i32 %i) "less-precise-fpmad"="false" {
    227   %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
    228   ret i32 %1
    229 ; CHECK: @test_less-precise-fpmad0(i32 %i) [[FPMAD_FALSE]] {
    230 ; CHECK-NEXT: ret i32
    231 }
    232 
    233 define i32 @test_less-precise-fpmad1(i32 %i) "less-precise-fpmad"="false" {
    234   %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
    235   ret i32 %1
    236 ; CHECK: @test_less-precise-fpmad1(i32 %i) [[FPMAD_FALSE]] {
    237 ; CHECK-NEXT: ret i32
    238 }
    239 
    240 define i32 @test_less-precise-fpmad2(i32 %i) "less-precise-fpmad"="true" {
    241   %1 = call i32 @less-precise-fpmad_callee0(i32 %i)
    242   ret i32 %1
    243 ; CHECK: @test_less-precise-fpmad2(i32 %i) [[FPMAD_FALSE]] {
    244 ; CHECK-NEXT: ret i32
    245 }
    246 
    247 define i32 @test_less-precise-fpmad3(i32 %i) "less-precise-fpmad"="true" {
    248   %1 = call i32 @less-precise-fpmad_callee1(i32 %i)
    249   ret i32 %1
    250 ; CHECK: @test_less-precise-fpmad3(i32 %i) [[FPMAD_TRUE]] {
    251 ; CHECK-NEXT: ret i32
    252 }
    253 
    254 define i32 @no-implicit-float_callee0(i32 %i) {
    255   ret i32 %i
    256 ; CHECK: @no-implicit-float_callee0(i32 %i) {
    257 ; CHECK-NEXT: ret i32
    258 }
    259 
    260 define i32 @no-implicit-float_callee1(i32 %i) noimplicitfloat {
    261   ret i32 %i
    262 ; CHECK: @no-implicit-float_callee1(i32 %i) [[NOIMPLICITFLOAT:#[0-9]+]] {
    263 ; CHECK-NEXT: ret i32
    264 }
    265 
    266 define i32 @test_no-implicit-float0(i32 %i) {
    267   %1 = call i32 @no-implicit-float_callee0(i32 %i)
    268   ret i32 %1
    269 ; CHECK: @test_no-implicit-float0(i32 %i) {
    270 ; CHECK-NEXT: ret i32
    271 }
    272 
    273 define i32 @test_no-implicit-float1(i32 %i) {
    274   %1 = call i32 @no-implicit-float_callee1(i32 %i)
    275   ret i32 %1
    276 ; CHECK: @test_no-implicit-float1(i32 %i) [[NOIMPLICITFLOAT]] {
    277 ; CHECK-NEXT: ret i32
    278 }
    279 
    280 define i32 @test_no-implicit-float2(i32 %i) noimplicitfloat {
    281   %1 = call i32 @no-implicit-float_callee0(i32 %i)
    282   ret i32 %1
    283 ; CHECK: @test_no-implicit-float2(i32 %i) [[NOIMPLICITFLOAT]] {
    284 ; CHECK-NEXT: ret i32
    285 }
    286 
    287 define i32 @test_no-implicit-float3(i32 %i) noimplicitfloat {
    288   %1 = call i32 @no-implicit-float_callee1(i32 %i)
    289   ret i32 %1
    290 ; CHECK: @test_no-implicit-float3(i32 %i) [[NOIMPLICITFLOAT]] {
    291 ; CHECK-NEXT: ret i32
    292 }
    293 
    294 ; Check that no-jump-tables flag propagates from inlined callee to caller 
    295 
    296 define i32 @no-use-jump-tables_callee0(i32 %i) {
    297   ret i32 %i
    298 ; CHECK: @no-use-jump-tables_callee0(i32 %i) {
    299 ; CHECK-NEXT: ret i32
    300 }
    301 
    302 define i32 @no-use-jump-tables_callee1(i32 %i) "no-jump-tables"="true" {
    303   ret i32 %i
    304 ; CHECK: @no-use-jump-tables_callee1(i32 %i) [[NOUSEJUMPTABLES:#[0-9]+]] {
    305 ; CHECK-NEXT: ret i32
    306 }
    307 
    308 define i32 @test_no-use-jump-tables0(i32 %i) {
    309   %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
    310   ret i32 %1
    311 ; CHECK: @test_no-use-jump-tables0(i32 %i) {
    312 ; CHECK-NEXT: ret i32
    313 }
    314 
    315 define i32 @test_no-use-jump-tables1(i32 %i) {
    316   %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
    317   ret i32 %1
    318 ; CHECK: @test_no-use-jump-tables1(i32 %i) [[NOUSEJUMPTABLES]] {
    319 ; CHECK-NEXT: ret i32
    320 }
    321 
    322 define i32 @test_no-use-jump-tables2(i32 %i) "no-jump-tables"="true" {
    323   %1 = call i32 @no-use-jump-tables_callee0(i32 %i)
    324   ret i32 %1
    325 ; CHECK: @test_no-use-jump-tables2(i32 %i) [[NOUSEJUMPTABLES]] {
    326 ; CHECK-NEXT: ret i32
    327 }
    328 
    329 define i32 @test_no-use-jump-tables3(i32 %i) "no-jump-tables"="true" {
    330   %1 = call i32 @no-use-jump-tables_callee1(i32 %i)
    331   ret i32 %1
    332 ; CHECK: @test_no-use-jump-tables3(i32 %i) [[NOUSEJUMPTABLES]] {
    333 ; CHECK-NEXT: ret i32
    334 }
    335 
    336 ; Callee with "null-pointer-is-valid"="true" attribute should not be inlined
    337 ; into a caller without this attribute.
    338 ; Exception: alwaysinline callee can still be inlined but
    339 ; "null-pointer-is-valid"="true" should get copied to caller.
    340 
    341 define i32 @null-pointer-is-valid_callee0(i32 %i) "null-pointer-is-valid"="true" {
    342   ret i32 %i
    343 ; CHECK: @null-pointer-is-valid_callee0(i32 %i)
    344 ; CHECK-NEXT: ret i32
    345 }
    346 
    347 define i32 @null-pointer-is-valid_callee1(i32 %i) alwaysinline "null-pointer-is-valid"="true" {
    348   ret i32 %i
    349 ; CHECK: @null-pointer-is-valid_callee1(i32 %i)
    350 ; CHECK-NEXT: ret i32
    351 }
    352 
    353 define i32 @null-pointer-is-valid_callee2(i32 %i)  {
    354   ret i32 %i
    355 ; CHECK: @null-pointer-is-valid_callee2(i32 %i)
    356 ; CHECK-NEXT: ret i32
    357 }
    358 
    359 ; No inlining since caller does not have "null-pointer-is-valid"="true" attribute.
    360 define i32 @test_null-pointer-is-valid0(i32 %i) {
    361   %1 = call i32 @null-pointer-is-valid_callee0(i32 %i)
    362   ret i32 %1
    363 ; CHECK: @test_null-pointer-is-valid0(
    364 ; CHECK: call i32 @null-pointer-is-valid_callee0
    365 ; CHECK-NEXT: ret i32
    366 }
    367 
    368 ; alwaysinline should force inlining even when caller does not have
    369 ; "null-pointer-is-valid"="true" attribute. However, the attribute should be
    370 ; copied to caller.
    371 define i32 @test_null-pointer-is-valid1(i32 %i) "null-pointer-is-valid"="false" {
    372   %1 = call i32 @null-pointer-is-valid_callee1(i32 %i)
    373   ret i32 %1
    374 ; CHECK: @test_null-pointer-is-valid1(i32 %i) [[NULLPOINTERISVALID:#[0-9]+]] {
    375 ; CHECK-NEXT: ret i32
    376 }
    377 
    378 ; Can inline since both caller and callee have "null-pointer-is-valid"="true"
    379 ; attribute.
    380 define i32 @test_null-pointer-is-valid2(i32 %i) "null-pointer-is-valid"="true" {
    381   %1 = call i32 @null-pointer-is-valid_callee2(i32 %i)
    382   ret i32 %1
    383 ; CHECK: @test_null-pointer-is-valid2(i32 %i) [[NULLPOINTERISVALID]] {
    384 ; CHECK-NEXT: ret i32
    385 }
    386 
    387 ; CHECK: attributes [[FPMAD_FALSE]] = { "less-precise-fpmad"="false" }
    388 ; CHECK: attributes [[FPMAD_TRUE]] = { "less-precise-fpmad"="true" }
    389 ; CHECK: attributes [[NOIMPLICITFLOAT]] = { noimplicitfloat }
    390 ; CHECK: attributes [[NOUSEJUMPTABLES]] = { "no-jump-tables"="true" }
    391 ; CHECK: attributes [[NULLPOINTERISVALID]] = { "null-pointer-is-valid"="true" }
    392