1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --function-signature 2; RUN: opt < %s -ipsccp -S | FileCheck %s 3; PR36485 4; musttail call result can\'t be replaced with a constant, unless the call 5; can be removed 6 7declare i32 @external() 8 9define i8* @start(i8 %v) { 10; CHECK-LABEL: define {{[^@]+}}@start 11; CHECK-SAME: (i8 [[V:%.*]]) { 12; CHECK-NEXT: [[C1:%.*]] = icmp eq i8 [[V]], 0 13; CHECK-NEXT: br i1 [[C1]], label [[TRUE:%.*]], label [[FALSE:%.*]] 14; CHECK: true: 15; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @side_effects(i8 0) 16; CHECK-NEXT: ret i8* [[CA]] 17; CHECK: false: 18; CHECK-NEXT: [[C2:%.*]] = icmp eq i8 [[V]], 1 19; CHECK-NEXT: br i1 [[C2]], label [[C2_TRUE:%.*]], label [[C2_FALSE:%.*]] 20; CHECK: c2_true: 21; CHECK-NEXT: ret i8* null 22; CHECK: c2_false: 23; CHECK-NEXT: [[CA2:%.*]] = musttail call i8* @dont_zap_me(i8 [[V]]) 24; CHECK-NEXT: ret i8* [[CA2]] 25; 26 %c1 = icmp eq i8 %v, 0 27 br i1 %c1, label %true, label %false 28true: 29 %ca = musttail call i8* @side_effects(i8 %v) 30 ret i8* %ca 31false: 32 %c2 = icmp eq i8 %v, 1 33 br i1 %c2, label %c2_true, label %c2_false 34c2_true: 35 %ca1 = musttail call i8* @no_side_effects(i8 %v) 36 ret i8* %ca1 37c2_false: 38 %ca2 = musttail call i8* @dont_zap_me(i8 %v) 39 ret i8* %ca2 40} 41 42define internal i8* @side_effects(i8 %v) { 43; CHECK-LABEL: define {{[^@]+}}@side_effects 44; CHECK-SAME: (i8 [[V:%.*]]) { 45; CHECK-NEXT: [[I1:%.*]] = call i32 @external() 46; CHECK-NEXT: [[CA:%.*]] = musttail call i8* @start(i8 0) 47; CHECK-NEXT: ret i8* [[CA]] 48; 49 %i1 = call i32 @external() 50 51 ; since this goes back to `start` the SCPP should be see that the return value 52 ; is always `null`. 53 ; The call can't be removed due to `external` call above, though. 54 55 %ca = musttail call i8* @start(i8 %v) 56 57 ; Thus the result must be returned anyway 58 ret i8* %ca 59} 60 61; The call to this function is removed, so the return value must be zapped 62define internal i8* @no_side_effects(i8 %v) readonly nounwind willreturn { 63; CHECK-LABEL: define {{[^@]+}}@no_side_effects 64; CHECK-SAME: (i8 [[V:%.*]]) #[[ATTR0:[0-9]+]] { 65; CHECK-NEXT: ret i8* undef 66; 67 ret i8* null 68} 69 70; The call to this function cannot be removed due to side effects. Thus the 71; return value should stay as it is, and should not be zapped. 72define internal i8* @dont_zap_me(i8 %v) { 73; CHECK-LABEL: define {{[^@]+}}@dont_zap_me 74; CHECK-SAME: (i8 [[V:%.*]]) { 75; CHECK-NEXT: [[I1:%.*]] = call i32 @external() 76; CHECK-NEXT: ret i8* null 77; 78 %i1 = call i32 @external() 79 ret i8* null 80} 81