1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 2; RUN: opt -passes=instcombine -S < %s | FileCheck %s 3; 4target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 5 6declare void @foo(ptr) 7declare void @bar(ptr addrspace(1)) 8 9define void @nonnullAfterBitCast() { 10; CHECK-LABEL: define void @nonnullAfterBitCast() { 11; CHECK-NEXT: entry: 12; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4 13; CHECK-NEXT: call void @foo(ptr nonnull [[I]]) 14; CHECK-NEXT: ret void 15; 16entry: 17 %i = alloca i32, align 4 18 call void @foo(ptr %i) 19 ret void 20} 21 22define void @nonnullAfterSExt(i8 %a) { 23; CHECK-LABEL: define void @nonnullAfterSExt 24; CHECK-SAME: (i8 [[A:%.*]]) { 25; CHECK-NEXT: entry: 26; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i64 27; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[B]], 2 28; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to ptr 29; CHECK-NEXT: call void @foo(ptr nonnull [[I2P]]) 30; CHECK-NEXT: ret void 31; 32entry: 33 %b = zext i8 %a to i32 ; <- %b is >= 0 34 %c = add nsw nuw i32 %b, 2 ; <- %c is > 0 35 %sext = sext i32 %c to i64 ; <- %sext cannot be 0 because %c is not 0 36 %i2p = inttoptr i64 %sext to ptr ; <- no-op int2ptr cast 37 call void @foo(ptr %i2p) 38 ret void 39} 40 41define void @nonnullAfterZExt(i8 %a) { 42; CHECK-LABEL: define void @nonnullAfterZExt 43; CHECK-SAME: (i8 [[A:%.*]]) { 44; CHECK-NEXT: entry: 45; CHECK-NEXT: [[B:%.*]] = zext i8 [[A]] to i64 46; CHECK-NEXT: [[C:%.*]] = add nuw nsw i64 [[B]], 2 47; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[C]] to ptr 48; CHECK-NEXT: call void @foo(ptr nonnull [[I2P]]) 49; CHECK-NEXT: ret void 50; 51entry: 52 %b = zext i8 %a to i32 ; <- %b is >= 0 53 %c = add nsw nuw i32 %b, 2 ; <- %c is > 0 54 %zext = zext i32 %c to i64 ; <- %zext cannot be 0 because %c is not 0 55 %i2p = inttoptr i64 %zext to ptr ; <- no-op int2ptr cast 56 call void @foo(ptr %i2p) 57 ret void 58} 59 60declare void @llvm.assume(i1 %b) 61 62define void @nonnullAfterInt2Ptr(i32 %u, i64 %lu) { 63; CHECK-LABEL: define void @nonnullAfterInt2Ptr 64; CHECK-SAME: (i32 [[U:%.*]], i64 [[LU:%.*]]) { 65; CHECK-NEXT: entry: 66; CHECK-NEXT: [[NZ:%.*]] = sdiv exact i32 100, [[U]] 67; CHECK-NEXT: [[TMP0:%.*]] = zext i32 [[NZ]] to i64 68; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to ptr 69; CHECK-NEXT: call void @foo(ptr nonnull [[I2P]]) 70; CHECK-NEXT: [[NZ_2:%.*]] = sdiv exact i64 100, [[LU]] 71; CHECK-NEXT: [[I2P_2:%.*]] = inttoptr i64 [[NZ_2]] to ptr 72; CHECK-NEXT: call void @foo(ptr nonnull [[I2P_2]]) 73; CHECK-NEXT: ret void 74; 75entry: 76 %nz = sdiv exact i32 100, %u ; %nz cannot be null 77 %i2p = inttoptr i32 %nz to ptr ; extending int2ptr as sizeof(i32) < sizeof(ptr) 78 call void @foo(ptr %i2p) 79 80 %nz.2 = sdiv exact i64 100, %lu ; %nz.2 cannot be null 81 %i2p.2 = inttoptr i64 %nz.2 to ptr ; no-op int2ptr as sizeof(i64) == sizeof(ptr) 82 call void @foo(ptr %i2p.2) 83 ret void 84} 85 86define void @nonnullAfterPtr2Int() { 87; CHECK-LABEL: define void @nonnullAfterPtr2Int() { 88; CHECK-NEXT: entry: 89; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 90; CHECK-NEXT: call void @foo(ptr nonnull [[A]]) 91; CHECK-NEXT: ret void 92; 93entry: 94 %a = alloca i32 95 %p2i = ptrtoint ptr %a to i64 ; no-op ptr2int as sizeof(ptr) == sizeof(i64) 96 %i2p = inttoptr i64 %p2i to ptr 97 call void @foo(ptr %i2p) 98 ret void 99} 100 101define void @maybenullAfterInt2Ptr(i128 %llu) { 102; CHECK-LABEL: define void @maybenullAfterInt2Ptr 103; CHECK-SAME: (i128 [[LLU:%.*]]) { 104; CHECK-NEXT: entry: 105; CHECK-NEXT: [[CMP:%.*]] = icmp ne i128 [[LLU]], 0 106; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]]) 107; CHECK-NEXT: [[TMP0:%.*]] = trunc i128 [[LLU]] to i64 108; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP0]] to ptr 109; CHECK-NEXT: call void @foo(ptr [[I2P]]) 110; CHECK-NEXT: ret void 111; 112entry: 113 %cmp = icmp ne i128 %llu, 0 114 call void @llvm.assume(i1 %cmp) ; %llu != 0 115 %i2p = inttoptr i128 %llu to ptr ; truncating int2ptr as sizeof(i128) > sizeof(ptr) 116 call void @foo(ptr %i2p) 117 ret void 118} 119 120define void @maybenullAfterPtr2Int() { 121; CHECK-LABEL: define void @maybenullAfterPtr2Int() { 122; CHECK-NEXT: entry: 123; CHECK-NEXT: [[A:%.*]] = alloca i32, align 4 124; CHECK-NEXT: [[TMP0:%.*]] = ptrtoint ptr [[A]] to i64 125; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[TMP0]], 4294967292 126; CHECK-NEXT: [[I2P:%.*]] = inttoptr i64 [[TMP1]] to ptr 127; CHECK-NEXT: call void @foo(ptr [[I2P]]) 128; CHECK-NEXT: ret void 129; 130entry: 131 %a = alloca i32 132 %p2i = ptrtoint ptr %a to i32 ; truncating ptr2int as sizeof(ptr) > sizeof(i32) 133 %i2p = inttoptr i32 %p2i to ptr 134 call void @foo(ptr %i2p) 135 ret void 136} 137 138define void @maybenullAfterAddrspacecast(ptr nonnull %p) { 139; CHECK-LABEL: define void @maybenullAfterAddrspacecast 140; CHECK-SAME: (ptr nonnull [[P:%.*]]) { 141; CHECK-NEXT: entry: 142; CHECK-NEXT: [[ADDRSPCAST:%.*]] = addrspacecast ptr [[P]] to ptr addrspace(1) 143; CHECK-NEXT: call void @bar(ptr addrspace(1) [[ADDRSPCAST]]) 144; CHECK-NEXT: call void @foo(ptr nonnull [[P]]) 145; CHECK-NEXT: ret void 146; 147entry: 148 %addrspcast = addrspacecast ptr %p to ptr addrspace(1) 149 150; An address space cast can be "a no-op cast or a complex value modification, 151; depending on the target and the address space pair". As a consequence, we 152; cannot simply assume non-nullness of %p is preserved by the cast. 153 call void @bar(ptr addrspace(1) %addrspcast) 154 155 call void @foo(ptr %p) 156 ret void 157} 158