Home | History | Annotate | Download | only in InstSimplify
      1 ; RUN: opt < %s -instsimplify -S | FileCheck %s
      2 
      3 declare {i8, i1} @llvm.uadd.with.overflow.i8(i8 %a, i8 %b)
      4 declare {i8, i1} @llvm.usub.with.overflow.i8(i8 %a, i8 %b)
      5 declare {i8, i1} @llvm.ssub.with.overflow.i8(i8 %a, i8 %b)
      6 declare {i8, i1} @llvm.umul.with.overflow.i8(i8 %a, i8 %b)
      7 
      8 define i1 @test_uadd1() {
      9 ; CHECK-LABEL: @test_uadd1(
     10   %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 254, i8 3)
     11   %overflow = extractvalue {i8, i1} %x, 1
     12   ret i1 %overflow
     13 ; CHECK-NEXT: ret i1 true
     14 }
     15 
     16 define i8 @test_uadd2() {
     17 ; CHECK-LABEL: @test_uadd2(
     18   %x = call {i8, i1} @llvm.uadd.with.overflow.i8(i8 254, i8 44)
     19   %result = extractvalue {i8, i1} %x, 0
     20   ret i8 %result
     21 ; CHECK-NEXT: ret i8 42
     22 }
     23 
     24 define {i8, i1} @test_usub1(i8 %V) {
     25 ; CHECK-LABEL: @test_usub1(
     26   %x = call {i8, i1} @llvm.usub.with.overflow.i8(i8 %V, i8 %V)
     27   ret {i8, i1} %x
     28 ; CHECK-NEXT: ret { i8, i1 } zeroinitializer
     29 }
     30 
     31 define {i8, i1} @test_ssub1(i8 %V) {
     32 ; CHECK-LABEL: @test_ssub1(
     33   %x = call {i8, i1} @llvm.ssub.with.overflow.i8(i8 %V, i8 %V)
     34   ret {i8, i1} %x
     35 ; CHECK-NEXT: ret { i8, i1 } zeroinitializer
     36 }
     37 
     38 define {i8, i1} @test_umul1(i8 %V) {
     39 ; CHECK-LABEL: @test_umul1(
     40   %x = call {i8, i1} @llvm.umul.with.overflow.i8(i8 %V, i8 0)
     41   ret {i8, i1} %x
     42 ; CHECK-NEXT: ret { i8, i1 } zeroinitializer
     43 }
     44 
     45 declare i256 @llvm.cttz.i256(i256 %src, i1 %is_zero_undef)
     46 
     47 define i256 @test_cttz() {
     48 ; CHECK-LABEL: @test_cttz(
     49   %x = call i256 @llvm.cttz.i256(i256 10, i1 false)
     50   ret i256 %x
     51 ; CHECK-NEXT: ret i256 1
     52 }
     53 
     54 declare i256 @llvm.ctpop.i256(i256 %src)
     55 
     56 define i256 @test_ctpop() {
     57 ; CHECK-LABEL: @test_ctpop(
     58   %x = call i256 @llvm.ctpop.i256(i256 10)
     59   ret i256 %x
     60 ; CHECK-NEXT: ret i256 2
     61 }
     62 
     63 ; Test a non-intrinsic that we know about as a library call.
     64 declare float @fabs(float %x)
     65 
     66 define float @test_fabs_libcall() {
     67 ; CHECK-LABEL: @test_fabs_libcall(
     68 
     69   %x = call float @fabs(float -42.0)
     70 ; This is still a real function call, so instsimplify won't nuke it -- other
     71 ; passes have to do that.
     72 ; CHECK-NEXT: call float @fabs
     73 
     74   ret float %x
     75 ; CHECK-NEXT: ret float 4.2{{0+}}e+01
     76 }
     77 
     78 
     79 declare float @llvm.fabs.f32(float) nounwind readnone
     80 declare float @llvm.floor.f32(float) nounwind readnone
     81 declare float @llvm.ceil.f32(float) nounwind readnone
     82 declare float @llvm.trunc.f32(float) nounwind readnone
     83 declare float @llvm.rint.f32(float) nounwind readnone
     84 declare float @llvm.nearbyint.f32(float) nounwind readnone
     85 
     86 ; Test idempotent intrinsics
     87 define float @test_idempotence(float %a) {
     88 ; CHECK-LABEL: @test_idempotence(
     89 
     90 ; CHECK: fabs
     91 ; CHECK-NOT: fabs
     92   %a0 = call float @llvm.fabs.f32(float %a)
     93   %a1 = call float @llvm.fabs.f32(float %a0)
     94 
     95 ; CHECK: floor
     96 ; CHECK-NOT: floor
     97   %b0 = call float @llvm.floor.f32(float %a)
     98   %b1 = call float @llvm.floor.f32(float %b0)
     99 
    100 ; CHECK: ceil
    101 ; CHECK-NOT: ceil
    102   %c0 = call float @llvm.ceil.f32(float %a)
    103   %c1 = call float @llvm.ceil.f32(float %c0)
    104 
    105 ; CHECK: trunc
    106 ; CHECK-NOT: trunc
    107   %d0 = call float @llvm.trunc.f32(float %a)
    108   %d1 = call float @llvm.trunc.f32(float %d0)
    109 
    110 ; CHECK: rint
    111 ; CHECK-NOT: rint
    112   %e0 = call float @llvm.rint.f32(float %a)
    113   %e1 = call float @llvm.rint.f32(float %e0)
    114 
    115 ; CHECK: nearbyint
    116 ; CHECK-NOT: nearbyint
    117   %f0 = call float @llvm.nearbyint.f32(float %a)
    118   %f1 = call float @llvm.nearbyint.f32(float %f0)
    119 
    120   %r0 = fadd float %a1, %b1
    121   %r1 = fadd float %r0, %c1
    122   %r2 = fadd float %r1, %d1
    123   %r3 = fadd float %r2, %e1
    124   %r4 = fadd float %r3, %f1
    125 
    126   ret float %r4
    127 }
    128 
    129 define i8* @operator_new() {
    130 entry:
    131   %call = tail call noalias i8* @_Znwm(i64 8)
    132   %cmp = icmp eq i8* %call, null
    133   br i1 %cmp, label %cast.end, label %cast.notnull
    134 
    135 cast.notnull:                                     ; preds = %entry
    136   %add.ptr = getelementptr inbounds i8, i8* %call, i64 4
    137   br label %cast.end
    138 
    139 cast.end:                                         ; preds = %cast.notnull, %entry
    140   %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
    141   ret i8* %cast.result
    142 
    143 ; CHECK-LABEL: @operator_new
    144 ; CHECK: br i1 false, label %cast.end, label %cast.notnull
    145 }
    146 
    147 declare noalias i8* @_Znwm(i64)
    148 
    149 %"struct.std::nothrow_t" = type { i8 }
    150 @_ZSt7nothrow = external global %"struct.std::nothrow_t"
    151 
    152 define i8* @operator_new_nothrow_t() {
    153 entry:
    154   %call = tail call noalias i8* @_ZnamRKSt9nothrow_t(i64 8, %"struct.std::nothrow_t"* @_ZSt7nothrow)
    155   %cmp = icmp eq i8* %call, null
    156   br i1 %cmp, label %cast.end, label %cast.notnull
    157 
    158 cast.notnull:                                     ; preds = %entry
    159   %add.ptr = getelementptr inbounds i8, i8* %call, i64 4
    160   br label %cast.end
    161 
    162 cast.end:                                         ; preds = %cast.notnull, %entry
    163   %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
    164   ret i8* %cast.result
    165 
    166 ; CHECK-LABEL: @operator_new_nothrow_t
    167 ; CHECK: br i1 %cmp, label %cast.end, label %cast.notnull
    168 }
    169 
    170 declare i8* @_ZnamRKSt9nothrow_t(i64, %"struct.std::nothrow_t"*) nounwind
    171 
    172 define i8* @malloc_can_return_null() {
    173 entry:
    174   %call = tail call noalias i8* @malloc(i64 8)
    175   %cmp = icmp eq i8* %call, null
    176   br i1 %cmp, label %cast.end, label %cast.notnull
    177 
    178 cast.notnull:                                     ; preds = %entry
    179   %add.ptr = getelementptr inbounds i8, i8* %call, i64 4
    180   br label %cast.end
    181 
    182 cast.end:                                         ; preds = %cast.notnull, %entry
    183   %cast.result = phi i8* [ %add.ptr, %cast.notnull ], [ null, %entry ]
    184   ret i8* %cast.result
    185 
    186 ; CHECK-LABEL: @malloc_can_return_null
    187 ; CHECK: br i1 %cmp, label %cast.end, label %cast.notnull
    188 }
    189 
    190 declare noalias i8* @malloc(i64)
    191