Home | History | Annotate | Download | only in reader_tests
      1 ; This tests parsing NaCl intrinsics not related to atomic operations.
      2 
      3 ; RUN: %p2i -i %s --insts --args -allow-externally-defined-symbols \
      4 ; RUN: | FileCheck %s
      5 ; RUN:   %p2i -i %s --args -notranslate -timing \
      6 ; RUN:        -allow-externally-defined-symbols | \
      7 ; RUN:   FileCheck --check-prefix=NOIR %s
      8 
      9 declare i8* @llvm.nacl.read.tp()
     10 declare void @llvm.memcpy.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
     11 declare void @llvm.memmove.p0i8.p0i8.i32(i8*, i8*, i32, i32, i1)
     12 declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i32, i1)
     13 declare void @llvm.nacl.longjmp(i8*, i32)
     14 declare i32 @llvm.nacl.setjmp(i8*)
     15 declare float @llvm.sqrt.f32(float)
     16 declare double @llvm.sqrt.f64(double)
     17 declare float @llvm.fabs.f32(float)
     18 declare double @llvm.fabs.f64(double)
     19 declare <4 x float> @llvm.fabs.v4f32(<4 x float>)
     20 declare void @llvm.trap()
     21 declare i16 @llvm.bswap.i16(i16)
     22 declare i32 @llvm.bswap.i32(i32)
     23 declare i64 @llvm.bswap.i64(i64)
     24 declare i32 @llvm.ctlz.i32(i32, i1)
     25 declare i64 @llvm.ctlz.i64(i64, i1)
     26 declare i32 @llvm.cttz.i32(i32, i1)
     27 declare i64 @llvm.cttz.i64(i64, i1)
     28 declare i32 @llvm.ctpop.i32(i32)
     29 declare i64 @llvm.ctpop.i64(i64)
     30 declare i8* @llvm.stacksave()
     31 declare void @llvm.stackrestore(i8*)
     32 
     33 define internal i32 @test_nacl_read_tp() {
     34 entry:
     35   %ptr = call i8* @llvm.nacl.read.tp()
     36   %__1 = ptrtoint i8* %ptr to i32
     37   ret i32 %__1
     38 }
     39 
     40 ; CHECK:      define internal i32 @test_nacl_read_tp() {
     41 ; CHECK-NEXT: entry:
     42 ; CHECK-NEXT:   %ptr = call i32 @llvm.nacl.read.tp()
     43 ; CHECK-NEXT:   ret i32 %ptr
     44 ; CHECK-NEXT: }
     45 
     46 define internal void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
     47 entry:
     48   %dst = inttoptr i32 %iptr_dst to i8*
     49   %src = inttoptr i32 %iptr_src to i8*
     50   call void @llvm.memcpy.p0i8.p0i8.i32(i8* %dst, i8* %src,
     51                                        i32 %len, i32 1, i1 false)
     52   ret void
     53 }
     54 
     55 ; CHECK-NEXT: define internal void @test_memcpy(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
     56 ; CHECK-NEXT: entry:
     57 ; CHECK-NEXT:   call void @llvm.memcpy.p0i8.p0i8.i32(i32 %iptr_dst, i32 %iptr_src, i32 %len, i32 1, i1 false)
     58 ; CHECK-NEXT:   ret void
     59 ; CHECK-NEXT: }
     60 
     61 define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
     62 entry:
     63   %dst = inttoptr i32 %iptr_dst to i8*
     64   %src = inttoptr i32 %iptr_src to i8*
     65   call void @llvm.memmove.p0i8.p0i8.i32(i8* %dst, i8* %src,
     66                                         i32 %len, i32 1, i1 false)
     67   ret void
     68 }
     69 
     70 ; CHECK-NEXT: define internal void @test_memmove(i32 %iptr_dst, i32 %iptr_src, i32 %len) {
     71 ; CHECK-NEXT: entry:
     72 ; CHECK-NEXT:   call void @llvm.memmove.p0i8.p0i8.i32(i32 %iptr_dst, i32 %iptr_src, i32 %len, i32 1, i1 false)
     73 ; CHECK-NEXT:   ret void
     74 ; CHECK-NEXT: }
     75 
     76 define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) {
     77 entry:
     78   %val = trunc i32 %wide_val to i8
     79   %dst = inttoptr i32 %iptr_dst to i8*
     80   call void @llvm.memset.p0i8.i32(i8* %dst, i8 %val,
     81                                   i32 %len, i32 1, i1 false)
     82   ret void
     83 }
     84 
     85 ; CHECK-NEXT: define internal void @test_memset(i32 %iptr_dst, i32 %wide_val, i32 %len) {
     86 ; CHECK-NEXT: entry:
     87 ; CHECK-NEXT:   %val = trunc i32 %wide_val to i8
     88 ; CHECK-NEXT:   call void @llvm.memset.p0i8.i32(i32 %iptr_dst, i8 %val, i32 %len, i32 1, i1 false)
     89 ; CHECK-NEXT:   ret void
     90 ; CHECK-NEXT: }
     91 
     92 define internal i32 @test_setjmplongjmp(i32 %iptr_env) {
     93 entry:
     94   %env = inttoptr i32 %iptr_env to i8*
     95   %i = call i32 @llvm.nacl.setjmp(i8* %env)
     96   %r1 = icmp eq i32 %i, 0
     97   br i1 %r1, label %Zero, label %NonZero
     98 Zero:
     99   ; Redundant inttoptr, to make --pnacl cast-eliding/re-insertion happy.
    100   %env2 = inttoptr i32 %iptr_env to i8*
    101   call void @llvm.nacl.longjmp(i8* %env2, i32 1)
    102   ret i32 0
    103 NonZero:
    104   ret i32 1
    105 }
    106 
    107 ; CHECK-NEXT: define internal i32 @test_setjmplongjmp(i32 %iptr_env) {
    108 ; CHECK-NEXT: entry:
    109 ; CHECK-NEXT:   %i = call i32 @llvm.nacl.setjmp(i32 %iptr_env)
    110 ; CHECK-NEXT:   %r1 = icmp eq i32 %i, 0
    111 ; CHECK-NEXT:   br i1 %r1, label %Zero, label %NonZero
    112 ; CHECK-NEXT: Zero:
    113 ; CHECK-NEXT:   call void @llvm.nacl.longjmp(i32 %iptr_env, i32 1)
    114 ; CHECK-NEXT:   ret i32 0
    115 ; CHECK-NEXT: NonZero:
    116 ; CHECK-NEXT:   ret i32 1
    117 ; CHECK-NEXT: }
    118 
    119 define internal float @test_sqrt_float(float %x, i32 %iptr) {
    120 entry:
    121   %r = call float @llvm.sqrt.f32(float %x)
    122   %r2 = call float @llvm.sqrt.f32(float %r)
    123   %r3 = call float @llvm.sqrt.f32(float -0.0)
    124   %r4 = fadd float %r2, %r3
    125   ret float %r4
    126 }
    127 
    128 ; CHECK-NEXT: define internal float @test_sqrt_float(float %x, i32 %iptr) {
    129 ; CHECK-NEXT: entry:
    130 ; CHECK-NEXT:   %r = call float @llvm.sqrt.f32(float %x)
    131 ; CHECK-NEXT:   %r2 = call float @llvm.sqrt.f32(float %r)
    132 ; CHECK-NEXT:   %r3 = call float @llvm.sqrt.f32(float -0.000000e+00)
    133 ; CHECK-NEXT:   %r4 = fadd float %r2, %r3
    134 ; CHECK-NEXT:   ret float %r4
    135 ; CHECK-NEXT: }
    136 
    137 define internal double @test_sqrt_double(double %x, i32 %iptr) {
    138 entry:
    139   %r = call double @llvm.sqrt.f64(double %x)
    140   %r2 = call double @llvm.sqrt.f64(double %r)
    141   %r3 = call double @llvm.sqrt.f64(double -0.0)
    142   %r4 = fadd double %r2, %r3
    143   ret double %r4
    144 }
    145 
    146 ; CHECK-NEXT: define internal double @test_sqrt_double(double %x, i32 %iptr) {
    147 ; CHECK-NEXT: entry:
    148 ; CHECK-NEXT:   %r = call double @llvm.sqrt.f64(double %x)
    149 ; CHECK-NEXT:   %r2 = call double @llvm.sqrt.f64(double %r)
    150 ; CHECK-NEXT:   %r3 = call double @llvm.sqrt.f64(double -0.000000e+00)
    151 ; CHECK-NEXT:   %r4 = fadd double %r2, %r3
    152 ; CHECK-NEXT:   ret double %r4
    153 ; CHECK-NEXT: }
    154 
    155 define internal float @test_fabs_float(float %x) {
    156 entry:
    157   %r = call float @llvm.fabs.f32(float %x)
    158   %r2 = call float @llvm.fabs.f32(float %r)
    159   %r3 = call float @llvm.fabs.f32(float -0.0)
    160   %r4 = fadd float %r2, %r3
    161   ret float %r4
    162 }
    163 
    164 ; CHECK-NEXT: define internal float @test_fabs_float(float %x) {
    165 ; CHECK-NEXT: entry:
    166 ; CHECK-NEXT:   %r = call float @llvm.fabs.f32(float %x)
    167 ; CHECK-NEXT:   %r2 = call float @llvm.fabs.f32(float %r)
    168 ; CHECK-NEXT:   %r3 = call float @llvm.fabs.f32(float -0.000000e+00)
    169 ; CHECK-NEXT:   %r4 = fadd float %r2, %r3
    170 ; CHECK-NEXT:   ret float %r4
    171 ; CHECK-NEXT: }
    172 
    173 define internal double @test_fabs_double(double %x) {
    174 entry:
    175   %r = call double @llvm.fabs.f64(double %x)
    176   %r2 = call double @llvm.fabs.f64(double %r)
    177   %r3 = call double @llvm.fabs.f64(double -0.0)
    178   %r4 = fadd double %r2, %r3
    179   ret double %r4
    180 }
    181 
    182 ; CHECK-NEXT: define internal double @test_fabs_double(double %x) {
    183 ; CHECK-NEXT: entry:
    184 ; CHECK-NEXT:   %r = call double @llvm.fabs.f64(double %x)
    185 ; CHECK-NEXT:   %r2 = call double @llvm.fabs.f64(double %r)
    186 ; CHECK-NEXT:   %r3 = call double @llvm.fabs.f64(double -0.000000e+00)
    187 ; CHECK-NEXT:   %r4 = fadd double %r2, %r3
    188 ; CHECK-NEXT:   ret double %r4
    189 ; CHECK-NEXT: }
    190 
    191 define internal <4 x float> @test_fabs_v4f32(<4 x float> %x) {
    192 entry:
    193   %r = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
    194   %r2 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %r)
    195   %r3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef)
    196   %r4 = fadd <4 x float> %r2, %r3
    197   ret <4 x float> %r4
    198 }
    199 
    200 ; CHECK-NEXT: define internal <4 x float> @test_fabs_v4f32(<4 x float> %x) {
    201 ; CHECK-NEXT: entry:
    202 ; CHECK-NEXT:   %r = call <4 x float> @llvm.fabs.v4f32(<4 x float> %x)
    203 ; CHECK-NEXT:   %r2 = call <4 x float> @llvm.fabs.v4f32(<4 x float> %r)
    204 ; CHECK-NEXT:   %r3 = call <4 x float> @llvm.fabs.v4f32(<4 x float> undef)
    205 ; CHECK-NEXT:   %r4 = fadd <4 x float> %r2, %r3
    206 ; CHECK-NEXT:   ret <4 x float> %r4
    207 ; CHECK-NEXT: }
    208 
    209 define internal i32 @test_trap(i32 %br) {
    210 entry:
    211   %r1 = icmp eq i32 %br, 0
    212   br i1 %r1, label %Zero, label %NonZero
    213 Zero:
    214   call void @llvm.trap()
    215   unreachable
    216 NonZero:
    217   ret i32 1
    218 }
    219 
    220 ; CHECK-NEXT: define internal i32 @test_trap(i32 %br) {
    221 ; CHECK-NEXT: entry:
    222 ; CHECK-NEXT:   %r1 = icmp eq i32 %br, 0
    223 ; CHECK-NEXT:   br i1 %r1, label %Zero, label %NonZero
    224 ; CHECK-NEXT: Zero:
    225 ; CHECK-NEXT:   call void @llvm.trap()
    226 ; CHECK-NEXT:   unreachable
    227 ; CHECK-NEXT: NonZero:
    228 ; CHECK-NEXT:   ret i32 1
    229 ; CHECK-NEXT: }
    230 
    231 define internal i32 @test_bswap_16(i32 %x) {
    232 entry:
    233   %x_trunc = trunc i32 %x to i16
    234   %r = call i16 @llvm.bswap.i16(i16 %x_trunc)
    235   %r_zext = zext i16 %r to i32
    236   ret i32 %r_zext
    237 }
    238 
    239 ; CHECK-NEXT: define internal i32 @test_bswap_16(i32 %x) {
    240 ; CHECK-NEXT: entry:
    241 ; CHECK-NEXT:   %x_trunc = trunc i32 %x to i16
    242 ; CHECK-NEXT:   %r = call i16 @llvm.bswap.i16(i16 %x_trunc)
    243 ; CHECK-NEXT:   %r_zext = zext i16 %r to i32
    244 ; CHECK-NEXT:   ret i32 %r_zext
    245 ; CHECK-NEXT: }
    246 
    247 define internal i32 @test_bswap_32(i32 %x) {
    248 entry:
    249   %r = call i32 @llvm.bswap.i32(i32 %x)
    250   ret i32 %r
    251 }
    252 
    253 ; CHECK-NEXT: define internal i32 @test_bswap_32(i32 %x) {
    254 ; CHECK-NEXT: entry:
    255 ; CHECK-NEXT:   %r = call i32 @llvm.bswap.i32(i32 %x)
    256 ; CHECK-NEXT:   ret i32 %r
    257 ; CHECK-NEXT: }
    258 
    259 define internal i64 @test_bswap_64(i64 %x) {
    260 entry:
    261   %r = call i64 @llvm.bswap.i64(i64 %x)
    262   ret i64 %r
    263 }
    264 
    265 ; CHECK-NEXT: define internal i64 @test_bswap_64(i64 %x) {
    266 ; CHECK-NEXT: entry:
    267 ; CHECK-NEXT:   %r = call i64 @llvm.bswap.i64(i64 %x)
    268 ; CHECK-NEXT:   ret i64 %r
    269 ; CHECK-NEXT: }
    270 
    271 define internal i32 @test_ctlz_32(i32 %x) {
    272 entry:
    273   %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
    274   ret i32 %r
    275 }
    276 
    277 ; CHECK-NEXT: define internal i32 @test_ctlz_32(i32 %x) {
    278 ; CHECK-NEXT: entry:
    279 ; CHECK-NEXT:   %r = call i32 @llvm.ctlz.i32(i32 %x, i1 false)
    280 ; CHECK-NEXT:   ret i32 %r
    281 ; CHECK-NEXT: }
    282 
    283 define internal i64 @test_ctlz_64(i64 %x) {
    284 entry:
    285   %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false)
    286   ret i64 %r
    287 }
    288 
    289 ; CHECK-NEXT: define internal i64 @test_ctlz_64(i64 %x) {
    290 ; CHECK-NEXT: entry:
    291 ; CHECK-NEXT:   %r = call i64 @llvm.ctlz.i64(i64 %x, i1 false)
    292 ; CHECK-NEXT:   ret i64 %r
    293 ; CHECK-NEXT: }
    294 
    295 define internal i32 @test_cttz_32(i32 %x) {
    296 entry:
    297   %r = call i32 @llvm.cttz.i32(i32 %x, i1 false)
    298   ret i32 %r
    299 }
    300 
    301 ; CHECK-NEXT: define internal i32 @test_cttz_32(i32 %x) {
    302 ; CHECK-NEXT: entry:
    303 ; CHECK-NEXT:   %r = call i32 @llvm.cttz.i32(i32 %x, i1 false)
    304 ; CHECK-NEXT:   ret i32 %r
    305 ; CHECK-NEXT: }
    306 
    307 define internal i64 @test_cttz_64(i64 %x) {
    308 entry:
    309   %r = call i64 @llvm.cttz.i64(i64 %x, i1 false)
    310   ret i64 %r
    311 }
    312 
    313 ; CHECK-NEXT: define internal i64 @test_cttz_64(i64 %x) {
    314 ; CHECK-NEXT: entry:
    315 ; CHECK-NEXT:   %r = call i64 @llvm.cttz.i64(i64 %x, i1 false)
    316 ; CHECK-NEXT:   ret i64 %r
    317 ; CHECK-NEXT: }
    318 
    319 define internal i32 @test_popcount_32(i32 %x) {
    320 entry:
    321   %r = call i32 @llvm.ctpop.i32(i32 %x)
    322   ret i32 %r
    323 }
    324 
    325 ; CHECK-NEXT: define internal i32 @test_popcount_32(i32 %x) {
    326 ; CHECK-NEXT: entry:
    327 ; CHECK-NEXT:   %r = call i32 @llvm.ctpop.i32(i32 %x)
    328 ; CHECK-NEXT:   ret i32 %r
    329 ; CHECK-NEXT: }
    330 
    331 define internal i64 @test_popcount_64(i64 %x) {
    332 entry:
    333   %r = call i64 @llvm.ctpop.i64(i64 %x)
    334   ret i64 %r
    335 }
    336 
    337 ; CHECK-NEXT: define internal i64 @test_popcount_64(i64 %x) {
    338 ; CHECK-NEXT: entry:
    339 ; CHECK-NEXT:   %r = call i64 @llvm.ctpop.i64(i64 %x)
    340 ; CHECK-NEXT:   ret i64 %r
    341 ; CHECK-NEXT: }
    342 
    343 define internal void @test_stacksave_noalloca() {
    344 entry:
    345   %sp = call i8* @llvm.stacksave()
    346   call void @llvm.stackrestore(i8* %sp)
    347   ret void
    348 }
    349 
    350 ; CHECK-NEXT: define internal void @test_stacksave_noalloca() {
    351 ; CHECK-NEXT: entry:
    352 ; CHECK-NEXT:   %sp = call i32 @llvm.stacksave()
    353 ; CHECK-NEXT:   call void @llvm.stackrestore(i32 %sp)
    354 ; CHECK-NEXT:   ret void
    355 ; CHECK-NEXT: }
    356 
    357 declare i32 @foo(i32 %x)
    358 
    359 define internal void @test_stacksave_multiple(i32 %x) {
    360 entry:
    361   %x_4 = mul i32 %x, 4
    362   %sp1 = call i8* @llvm.stacksave()
    363   %tmp1 = alloca i8, i32 %x_4, align 4
    364 
    365   %sp2 = call i8* @llvm.stacksave()
    366   %tmp2 = alloca i8, i32 %x_4, align 4
    367 
    368   %y = call i32 @foo(i32 %x)
    369 
    370   %sp3 = call i8* @llvm.stacksave()
    371   %tmp3 = alloca i8, i32 %x_4, align 4
    372 
    373   %__9 = bitcast i8* %tmp1 to i32*
    374   store i32 %y, i32* %__9, align 1
    375 
    376   %__10 = bitcast i8* %tmp2 to i32*
    377   store i32 %x, i32* %__10, align 1
    378 
    379   %__11 = bitcast i8* %tmp3 to i32*
    380   store i32 %x, i32* %__11, align 1
    381 
    382   call void @llvm.stackrestore(i8* %sp1)
    383   ret void
    384 }
    385 
    386 ; CHECK-NEXT: define internal void @test_stacksave_multiple(i32 %x) {
    387 ; CHECK-NEXT: entry:
    388 ; CHECK-NEXT:   %x_4 = mul i32 %x, 4
    389 ; CHECK-NEXT:   %sp1 = call i32 @llvm.stacksave()
    390 ; CHECK-NEXT:   %tmp1 = alloca i8, i32 %x_4, align 4
    391 ; CHECK-NEXT:   %sp2 = call i32 @llvm.stacksave()
    392 ; CHECK-NEXT:   %tmp2 = alloca i8, i32 %x_4, align 4
    393 ; CHECK-NEXT:   %y = call i32 @foo(i32 %x)
    394 ; CHECK-NEXT:   %sp3 = call i32 @llvm.stacksave()
    395 ; CHECK-NEXT:   %tmp3 = alloca i8, i32 %x_4, align 4
    396 ; CHECK-NEXT:   store i32 %y, i32* %tmp1, align 1
    397 ; CHECK-NEXT:   store i32 %x, i32* %tmp2, align 1
    398 ; CHECK-NEXT:   store i32 %x, i32* %tmp3, align 1
    399 ; CHECK-NEXT:   call void @llvm.stackrestore(i32 %sp1)
    400 ; CHECK-NEXT:   ret void
    401 ; CHECK-NEXT: }
    402 
    403 ; NOIR: Total across all functions
    404