1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt -S -instsimplify < %s | FileCheck %s 3 4declare void @bar(i8* %a, i8* nonnull %b) 5 6; 'y' must be nonnull. 7 8define i1 @caller1(i8* %x, i8* %y) { 9; CHECK-LABEL: @caller1( 10; CHECK-NEXT: call void @bar(i8* %x, i8* %y) 11; CHECK-NEXT: ret i1 false 12; 13 call void @bar(i8* %x, i8* %y) 14 %null_check = icmp eq i8* %y, null 15 ret i1 %null_check 16} 17 18; Don't know anything about 'y'. 19 20define i1 @caller2(i8* %x, i8* %y) { 21; CHECK-LABEL: @caller2( 22; CHECK-NEXT: call void @bar(i8* %y, i8* %x) 23; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %y, null 24; CHECK-NEXT: ret i1 [[NULL_CHECK]] 25; 26 call void @bar(i8* %y, i8* %x) 27 %null_check = icmp eq i8* %y, null 28 ret i1 %null_check 29} 30 31; 'y' must be nonnull. 32 33define i1 @caller3(i8* %x, i8* %y) { 34; CHECK-LABEL: @caller3( 35; CHECK-NEXT: call void @bar(i8* %x, i8* %y) 36; CHECK-NEXT: ret i1 true 37; 38 call void @bar(i8* %x, i8* %y) 39 %null_check = icmp ne i8* %y, null 40 ret i1 %null_check 41} 42 43; FIXME: The call is guaranteed to execute, so 'y' must be nonnull throughout. 44 45define i1 @caller4(i8* %x, i8* %y) { 46; CHECK-LABEL: @caller4( 47; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp ne i8* %y, null 48; CHECK-NEXT: call void @bar(i8* %x, i8* %y) 49; CHECK-NEXT: ret i1 [[NULL_CHECK]] 50; 51 %null_check = icmp ne i8* %y, null 52 call void @bar(i8* %x, i8* %y) 53 ret i1 %null_check 54} 55 56; The call to bar() does not dominate the null check, so no change. 57 58define i1 @caller5(i8* %x, i8* %y) { 59; CHECK-LABEL: @caller5( 60; CHECK-NEXT: [[NULL_CHECK:%.*]] = icmp eq i8* %y, null 61; CHECK-NEXT: br i1 [[NULL_CHECK]], label %t, label %f 62; CHECK: t: 63; CHECK-NEXT: ret i1 [[NULL_CHECK]] 64; CHECK: f: 65; CHECK-NEXT: call void @bar(i8* %x, i8* %y) 66; CHECK-NEXT: ret i1 [[NULL_CHECK]] 67; 68 %null_check = icmp eq i8* %y, null 69 br i1 %null_check, label %t, label %f 70t: 71 ret i1 %null_check 72f: 73 call void @bar(i8* %x, i8* %y) 74 ret i1 %null_check 75} 76 77; Make sure that an invoke works similarly to a call. 78 79declare i32 @esfp(...) 80 81define i1 @caller6(i8* %x, i8* %y) personality i8* bitcast (i32 (...)* @esfp to i8*){ 82; CHECK-LABEL: @caller6( 83; CHECK-NEXT: invoke void @bar(i8* %x, i8* nonnull %y) 84; CHECK-NEXT: to label %cont unwind label %exc 85; CHECK: cont: 86; CHECK-NEXT: ret i1 false 87; 88 invoke void @bar(i8* %x, i8* nonnull %y) 89 to label %cont unwind label %exc 90 91cont: 92 %null_check = icmp eq i8* %y, null 93 ret i1 %null_check 94 95exc: 96 %lp = landingpad { i8*, i32 } 97 filter [0 x i8*] zeroinitializer 98 unreachable 99} 100 101declare i8* @returningPtr(i8* returned %p) 102 103define i1 @nonnullReturnTest(i8* nonnull %x) { 104; CHECK-LABEL: @nonnullReturnTest( 105; CHECK-NEXT: %x2 = call i8* @returningPtr(i8* %x) 106; CHECK-NEXT: ret i1 false 107 %x2 = call i8* @returningPtr(i8* %x) 108 %null_check = icmp eq i8* %x2, null 109 ret i1 %null_check 110} 111 112define i1 @unknownReturnTest(i8* %x) { 113; CHECK-LABEL: @unknownReturnTest( 114; CHECK-NEXT: %x2 = call i8* @returningPtr(i8* %x) 115; CHECK-NEXT: %null_check = icmp eq i8* %x2, null 116; CHECK-NEXT: ret i1 %null_check 117 %x2 = call i8* @returningPtr(i8* %x) 118 %null_check = icmp eq i8* %x2, null 119 ret i1 %null_check 120} 121 122