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