1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3; PR1201 4 5target datalayout = "p:32:32:32" 6 7define i32 @main(i32 %argc, i8** %argv) { 8; CHECK-LABEL: @main( 9; CHECK-NEXT: ret i32 0 10; 11 %c_19 = alloca i8* 12 %malloc_206 = tail call i8* @malloc(i32 mul (i32 ptrtoint (i8* getelementptr (i8, i8* null, i32 1) to i32), i32 10)) 13 store i8* %malloc_206, i8** %c_19 14 %tmp_207 = load i8*, i8** %c_19 15 tail call void @free(i8* %tmp_207) 16 ret i32 0 17} 18 19define i32 @dead_aligned_alloc(i32 %size, i32 %alignment, i8 %value) { 20; CHECK-LABEL: @dead_aligned_alloc( 21; CHECK-NEXT: ret i32 0 22; 23 %aligned_allocation = tail call i8* @aligned_alloc(i32 %alignment, i32 %size) 24 store i8 %value, i8* %aligned_allocation 25 tail call void @free(i8* %aligned_allocation) 26 ret i32 0 27} 28 29declare noalias i8* @calloc(i32, i32) nounwind 30declare noalias i8* @malloc(i32) 31declare noalias i8* @aligned_alloc(i32, i32) 32declare void @free(i8*) 33 34define i1 @foo() { 35; CHECK-LABEL: @foo( 36; CHECK-NEXT: ret i1 false 37; 38 %m = call i8* @malloc(i32 1) 39 %z = icmp eq i8* %m, null 40 call void @free(i8* %m) 41 ret i1 %z 42} 43 44declare void @llvm.lifetime.start.p0i8(i64, i8*) 45declare void @llvm.lifetime.end.p0i8(i64, i8*) 46declare i64 @llvm.objectsize.i64(i8*, i1) 47declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind 48declare void @llvm.memmove.p0i8.p0i8.i32(i8* nocapture, i8* nocapture, i32, i1) nounwind 49declare void @llvm.memset.p0i8.i32(i8*, i8, i32, i1) nounwind 50 51define void @test3(i8* %src) { 52; CHECK-LABEL: @test3( 53; CHECK-NEXT: ret void 54; 55 %a = call noalias i8* @malloc(i32 10) 56 call void @llvm.lifetime.start.p0i8(i64 10, i8* %a) 57 call void @llvm.lifetime.end.p0i8(i64 10, i8* %a) 58 %size = call i64 @llvm.objectsize.i64(i8* %a, i1 true) 59 store i8 42, i8* %a 60 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %a, i8* %src, i32 32, i1 false) 61 call void @llvm.memmove.p0i8.p0i8.i32(i8* %a, i8* %src, i32 32, i1 false) 62 call void @llvm.memset.p0i8.i32(i8* %a, i8 5, i32 32, i1 false) 63 %alloc2 = call noalias i8* @calloc(i32 5, i32 7) nounwind 64 %z = icmp ne i8* %alloc2, null 65 ret void 66} 67 68;; This used to crash. 69define void @test4() { 70; CHECK-LABEL: @test4( 71; CHECK-NEXT: ret void 72; 73 %A = call i8* @malloc(i32 16000) 74 %B = bitcast i8* %A to double* 75 %C = bitcast double* %B to i8* 76 call void @free(i8* %C) 77 ret void 78} 79 80define void @test5(i8* %ptr, i8** %esc) { 81; CHECK-LABEL: @test5( 82; CHECK-NEXT: [[A:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 83; CHECK-NEXT: [[B:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 84; CHECK-NEXT: [[C:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 85; CHECK-NEXT: [[D:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 86; CHECK-NEXT: [[E:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 87; CHECK-NEXT: [[F:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 88; CHECK-NEXT: [[G:%.*]] = call dereferenceable_or_null(700) i8* @malloc(i32 700) 89; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(32) [[PTR:%.*]], i8* noundef nonnull align 1 dereferenceable(32) [[A]], i32 32, i1 false) 90; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* noundef nonnull align 1 dereferenceable(32) [[PTR]], i8* noundef nonnull align 1 dereferenceable(32) [[B]], i32 32, i1 false) 91; CHECK-NEXT: store i8* [[C]], i8** [[ESC:%.*]], align 4 92; CHECK-NEXT: call void @llvm.memcpy.p0i8.p0i8.i32(i8* [[D]], i8* [[PTR]], i32 32, i1 true) 93; CHECK-NEXT: call void @llvm.memmove.p0i8.p0i8.i32(i8* [[E]], i8* [[PTR]], i32 32, i1 true) 94; CHECK-NEXT: call void @llvm.memset.p0i8.i32(i8* [[F]], i8 5, i32 32, i1 true) 95; CHECK-NEXT: store volatile i8 4, i8* [[G]], align 1 96; CHECK-NEXT: ret void 97; 98 %a = call i8* @malloc(i32 700) 99 %b = call i8* @malloc(i32 700) 100 %c = call i8* @malloc(i32 700) 101 %d = call i8* @malloc(i32 700) 102 %e = call i8* @malloc(i32 700) 103 %f = call i8* @malloc(i32 700) 104 %g = call i8* @malloc(i32 700) 105 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %ptr, i8* %a, i32 32, i1 false) 106 call void @llvm.memmove.p0i8.p0i8.i32(i8* %ptr, i8* %b, i32 32, i1 false) 107 store i8* %c, i8** %esc 108 call void @llvm.memcpy.p0i8.p0i8.i32(i8* %d, i8* %ptr, i32 32, i1 true) 109 call void @llvm.memmove.p0i8.p0i8.i32(i8* %e, i8* %ptr, i32 32, i1 true) 110 call void @llvm.memset.p0i8.i32(i8* %f, i8 5, i32 32, i1 true) 111 store volatile i8 4, i8* %g 112 ret void 113} 114 115;; When a basic block contains only a call to free and this block is accessed 116;; through a test of the argument of free against null, move the call in the 117;; predecessor block. 118;; Using simplifycfg will remove the empty basic block and the branch operation 119;; Then, performing a dead elimination will remove the comparison. 120;; This is what happens with -O1 and upper. 121define void @test6(i8* %foo) minsize { 122; CHECK-LABEL: @test6( 123; CHECK-NEXT: entry: 124; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[FOO:%.*]], null 125; CHECK-NEXT: tail call void @free(i8* [[FOO]]) 126; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 127; CHECK: if.then: 128; CHECK-NEXT: br label [[IF_END]] 129; CHECK: if.end: 130; CHECK-NEXT: ret void 131; 132;; Call to free moved 133;; Block is now empty and may be simplified by simplifycfg 134entry: 135 %tobool = icmp eq i8* %foo, null 136 br i1 %tobool, label %if.end, label %if.then 137 138if.then: ; preds = %entry 139 tail call void @free(i8* %foo) 140 br label %if.end 141 142if.end: ; preds = %entry, %if.then 143 ret void 144} 145 146;; Check that the optimization that moves a call to free in its predecessor 147;; block (see test6) also happens when noop casts are involved. 148define void @test12(i32* %foo) minsize { 149; CHECK-LABEL: @test12( 150; CHECK-NEXT: entry: 151; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32* [[FOO:%.*]], null 152; CHECK-NEXT: [[BITCAST:%.*]] = bitcast i32* [[FOO]] to i8* 153; CHECK-NEXT: tail call void @free(i8* [[BITCAST]]) 154; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 155; CHECK: if.then: 156; CHECK-NEXT: br label [[IF_END]] 157; CHECK: if.end: 158; CHECK-NEXT: ret void 159; 160;; Everything before the call to free should have been moved as well. 161;; Call to free moved 162;; Block is now empty and may be simplified by simplifycfg 163entry: 164 %tobool = icmp eq i32* %foo, null 165 br i1 %tobool, label %if.end, label %if.then 166 167if.then: ; preds = %entry 168 %bitcast = bitcast i32* %foo to i8* 169 tail call void @free(i8* %bitcast) 170 br label %if.end 171 172if.end: ; preds = %entry, %if.then 173 ret void 174} 175 176;; Test that nonnull-implying attributes on the parameter are adjusted when the 177;; call is moved, since they may no longer be valid and result in miscompiles if 178;; kept unchanged. 179define void @test_nonnull_free_move(i8* %foo) minsize { 180; CHECK-LABEL: @test_nonnull_free_move( 181; CHECK-NEXT: entry: 182; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[FOO:%.*]], null 183; CHECK-NEXT: tail call void @free(i8* [[FOO]]) 184; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 185; CHECK: if.then: 186; CHECK-NEXT: br label [[IF_END]] 187; CHECK: if.end: 188; CHECK-NEXT: ret void 189; 190entry: 191 %tobool = icmp eq i8* %foo, null 192 br i1 %tobool, label %if.end, label %if.then 193 194if.then: ; preds = %entry 195 tail call void @free(i8* nonnull %foo) 196 br label %if.end 197 198if.end: ; preds = %entry, %if.then 199 ret void 200} 201 202define void @test_dereferenceable_free_move(i8* %foo) minsize { 203; CHECK-LABEL: @test_dereferenceable_free_move( 204; CHECK-NEXT: entry: 205; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[FOO:%.*]], null 206; CHECK-NEXT: tail call void @free(i8* dereferenceable_or_null(4) [[FOO]]) 207; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 208; CHECK: if.then: 209; CHECK-NEXT: br label [[IF_END]] 210; CHECK: if.end: 211; CHECK-NEXT: ret void 212; 213entry: 214 %tobool = icmp eq i8* %foo, null 215 br i1 %tobool, label %if.end, label %if.then 216 217if.then: ; preds = %entry 218 tail call void @free(i8* dereferenceable(4) %foo) 219 br label %if.end 220 221if.end: ; preds = %entry, %if.then 222 ret void 223} 224 225define void @test_nonnull_dereferenceable_free_move(i8* %foo) minsize { 226; CHECK-LABEL: @test_nonnull_dereferenceable_free_move( 227; CHECK-NEXT: entry: 228; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i8* [[FOO:%.*]], null 229; CHECK-NEXT: tail call void @free(i8* dereferenceable_or_null(16) [[FOO]]) 230; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]] 231; CHECK: if.then: 232; CHECK-NEXT: br label [[IF_END]] 233; CHECK: if.end: 234; CHECK-NEXT: ret void 235; 236entry: 237 %tobool = icmp eq i8* %foo, null 238 br i1 %tobool, label %if.end, label %if.then 239 240if.then: ; preds = %entry 241 tail call void @free(i8* nonnull dereferenceable(16) %foo) 242 br label %if.end 243 244if.end: ; preds = %entry, %if.then 245 ret void 246} 247 248; The next four tests cover the semantics of the nofree attributes. These 249; are thought to be legal transforms, but an implementation thereof has 250; been reverted once due to difficult to isolate fallout. 251 252; TODO: Freeing a no-free pointer -> %foo must be null 253define void @test13(i8* nofree %foo) { 254; CHECK-LABEL: @test13( 255; CHECK-NEXT: call void @free(i8* [[FOO:%.*]]) 256; CHECK-NEXT: ret void 257; 258 call void @free(i8* %foo) 259 ret void 260} 261 262; TODO: Freeing a no-free pointer -> %foo must be null 263define void @test14(i8* %foo) nofree { 264; CHECK-LABEL: @test14( 265; CHECK-NEXT: call void @free(i8* [[FOO:%.*]]) 266; CHECK-NEXT: ret void 267; 268 call void @free(i8* %foo) 269 ret void 270} 271 272; TODO: free call marked no-free -> %foo must be null 273define void @test15(i8* %foo) { 274; CHECK-LABEL: @test15( 275; CHECK-NEXT: call void @free(i8* [[FOO:%.*]]) #[[ATTR5:[0-9]+]] 276; CHECK-NEXT: ret void 277; 278 call void @free(i8* %foo) nofree 279 ret void 280} 281 282; TODO: freeing a nonnull nofree pointer -> full UB 283define void @test16(i8* nonnull nofree %foo) { 284; CHECK-LABEL: @test16( 285; CHECK-NEXT: call void @free(i8* [[FOO:%.*]]) 286; CHECK-NEXT: ret void 287; 288 call void @free(i8* %foo) 289 ret void 290} 291