1; RUN: opt -S -dse < %s | FileCheck %s 2 3declare void @f() 4declare noalias i8* @malloc(i32) nounwind 5 6define void @test_0() { 7; CHECK-LABEL: @test_0( 8 %m = call i8* @malloc(i32 24) 9 tail call void @f() [ "unknown"(i8* %m) ] 10; CHECK: store i8 -19, i8* %m 11 store i8 -19, i8* %m 12 ret void 13} 14 15define i8* @test_1() { 16; CHECK-LABEL: @test_1( 17 %m = call i8* @malloc(i32 24) 18 tail call void @f() [ "unknown"(i8* %m) ] 19 store i8 -19, i8* %m 20 tail call void @f() 21 store i8 101, i8* %m 22 23; CHECK: tail call void @f() [ "unknown"(i8* %m) ] 24; CHECK: store i8 -19, i8* %m 25; CHECK: tail call void @f() 26; CHECK: store i8 101, i8* %m 27 28 ret i8* %m 29} 30 31define void @test_2() { 32; Since the deopt operand bundle does not escape %m (see caveat below), it is 33; legal to elide the final store that location. 34 35; CHECK-LABEL: @test_2( 36 %m = call i8* @malloc(i32 24) 37 tail call void @f() [ "deopt"(i8* %m) ] 38 store i8 -19, i8* %m 39 ret void 40 41; CHECK: tail call void @f() [ "deopt"(i8* %m) ] 42; CHECK-NEXT ret void 43} 44 45define i8* @test_3() { 46; Since the deopt operand bundle does not escape %m (see caveat below), @f 47; cannot observe the stores to %m 48 49; CHECK-LABEL: @test_3( 50 %m = call i8* @malloc(i32 24) 51 tail call void @f() [ "deopt"(i8* %m) ] 52 store i8 -19, i8* %m 53 tail call void @f() 54 store i8 101, i8* %m 55 ret i8* %m 56} 57 58 59; Caveat: technically, %m can only escape if the calling function is deoptimized 60; at the call site (i.e. the call returns to the "deopt" continuation). Since 61; the calling function body will be invalidated in that case, the calling 62; function can be optimized under the assumption that %m does not escape. 63