1; RUN: opt < %s -ipsccp -S | FileCheck %s 2; RUN: opt < %s -enable-debugify -ipsccp -debugify-quiet -disable-output 3 4;;======================== test1 5 6define internal i32 @test1a(i32 %A) { 7 %X = add i32 1, 2 8 ret i32 %A 9} 10; CHECK-LABEL: define internal i32 @test1a( 11; CHECK: ret i32 undef 12 13define i32 @test1b() { 14 %X = call i32 @test1a( i32 17 ) 15 ret i32 %X 16 17; CHECK-LABEL: define i32 @test1b( 18; CHECK: ret i32 17 19} 20 21 22 23;;======================== test2 24 25define internal i32 @test2a(i32 %A) { 26 %C = icmp eq i32 %A, 0 27 br i1 %C, label %T, label %F 28T: 29 %B = call i32 @test2a( i32 0 ) 30 ret i32 0 31F: 32 %C.upgrd.1 = call i32 @test2a(i32 1) 33 ret i32 %C.upgrd.1 34} 35; CHECK-LABEL: define internal i32 @test2a( 36; CHECK-NEXT: br label %T 37; CHECK: ret i32 undef 38 39 40define i32 @test2b() { 41 %X = call i32 @test2a(i32 0) 42 ret i32 %X 43} 44; CHECK-LABEL: define i32 @test2b( 45; CHECK-NEXT: %X = call i32 @test2a(i32 0) 46; CHECK-NEXT: ret i32 0 47 48 49;;======================== test3 50 51@G = internal global i32 undef 52 53define void @test3a() { 54 %X = load i32, i32* @G 55 store i32 %X, i32* @G 56 ret void 57} 58; CHECK-LABEL: define void @test3a( 59; CHECK-NEXT: %X = load i32, i32* @G 60; CHECK-NEXT: store i32 %X, i32* @G 61; CHECK-NEXT: ret void 62 63 64define i32 @test3b() { 65 %V = load i32, i32* @G 66 %C = icmp eq i32 %V, 17 67 br i1 %C, label %T, label %F 68T: 69 store i32 17, i32* @G 70 ret i32 %V 71F: 72 store i32 123, i32* @G 73 ret i32 0 74} 75; CHECK-LABEL: define i32 @test3b( 76; CHECK-NEXT: %V = load i32, i32* @G 77; CHECK-NEXT: %C = icmp eq i32 %V, 17 78; CHECK-NEXT: br i1 %C, label %T, label %F 79 80; CHECK-LABEL: T: 81; CHECK-NEXT: store i32 17, i32* @G 82; CHECK-NEXT: ret i32 17 83 84; CHECK-LABEL: F: 85; CHECK-NEXT: store i32 123, i32* @G 86; CHECK-NEXT: ret i32 0 87 88;;======================== test4 89 90define internal {i64,i64} @test4a() { 91 %a = insertvalue {i64,i64} undef, i64 4, 1 92 %b = insertvalue {i64,i64} %a, i64 5, 0 93 ret {i64,i64} %b 94} 95 96; CHECK-LABEL: define internal { i64, i64 } @test4a( 97; CHECK-NEXT: ret { i64, i64 } undef 98; CHECK-NEXT: } 99 100define i64 @test4b() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 101 %a = invoke {i64,i64} @test4a() 102 to label %A unwind label %B 103A: 104 %b = extractvalue {i64,i64} %a, 0 105 %c = call i64 @test4c(i64 %b) 106 ret i64 %c 107B: 108 %val = landingpad { i8*, i32 } 109 catch i8* null 110 ret i64 0 111} 112; CHECK: define i64 @test4b() 113; CHECK: %c = call i64 @test4c(i64 5) 114; CHECK-NEXT: ret i64 5 115 116 117define internal i64 @test4c(i64 %a) { 118 ret i64 %a 119} 120; CHECK-LABEL: define internal i64 @test4c( 121; CHECK: ret i64 undef 122 123 124 125;;======================== test5 126 127; PR4313 128define internal {i64,i64} @test5a() { 129 %a = insertvalue {i64,i64} undef, i64 4, 1 130 %b = insertvalue {i64,i64} %a, i64 5, 0 131 ret {i64,i64} %b 132} 133 134define i64 @test5b() personality i8* bitcast (i32 (...)* @__gxx_personality_v0 to i8*) { 135 %a = invoke {i64,i64} @test5a() 136 to label %A unwind label %B 137A: 138 %c = call i64 @test5c({i64,i64} %a) 139 ret i64 %c 140B: 141 %val = landingpad { i8*, i32 } 142 catch i8* null 143 ret i64 0 144} 145 146; CHECK: define i64 @test5b() 147; CHECK: A: 148; CHECK-NEXT: %c = call i64 @test5c({ i64, i64 } { i64 5, i64 4 }) 149; CHECK-NEXT: ret i64 5 150 151define internal i64 @test5c({i64,i64} %a) { 152 %b = extractvalue {i64,i64} %a, 0 153 ret i64 %b 154} 155 156 157;;======================== test6 158 159define i64 @test6a() { 160 ret i64 0 161} 162 163define i64 @test6b() { 164 %a = call i64 @test6a() 165 ret i64 %a 166} 167; CHECK-LABEL: define i64 @test6b( 168; CHECK: ret i64 0 169 170;;======================== test7 171 172 173%T = type {i32,i32} 174 175define internal %T @test7a(i32 %A) { 176 %X = add i32 1, %A 177 %mrv0 = insertvalue %T undef, i32 %X, 0 178 %mrv1 = insertvalue %T %mrv0, i32 %A, 1 179 ret %T %mrv1 180; CHECK-LABEL: @test7a( 181; CHECK-NEXT: ret %T undef 182} 183 184define i32 @test7b() { 185 %X = call %T @test7a(i32 17) 186 %Y = extractvalue %T %X, 0 187 %Z = add i32 %Y, %Y 188 ret i32 %Z 189; CHECK-LABEL: define i32 @test7b( 190; CHECK-NEXT: call %T @test7a(i32 17) 191; CHECK-NEXT: ret i32 36 192} 193 194;;======================== test8 195 196 197define internal {} @test8a(i32 %A, i32* %P) { 198 store i32 %A, i32* %P 199 ret {} {} 200; CHECK-LABEL: @test8a( 201; CHECK-NEXT: store i32 5, 202; CHECK-NEXT: ret 203} 204 205define void @test8b(i32* %P) { 206 %X = call {} @test8a(i32 5, i32* %P) 207 ret void 208; CHECK-LABEL: define void @test8b( 209; CHECK-NEXT: call {} @test8a 210; CHECK-NEXT: ret void 211} 212 213;;======================== test9 214 215@test9g = internal global { } zeroinitializer 216 217define void @test9() { 218entry: 219 %local_foo = alloca { } 220 load { }, { }* @test9g 221 store { } %0, { }* %local_foo 222 ret void 223} 224 225; CHECK-LABEL: define void @test9( 226; CHECK-NEXT: entry: 227; CHECK-NEXT: %local_foo = alloca {} 228; CHECK-NEXT: store {} zeroinitializer, {}* %local_foo 229; CHECK-NEXT: ret void 230 231declare i32 @__gxx_personality_v0(...) 232 233;;======================== test10 234 235define i32 @test10a() nounwind { 236entry: 237 %call = call i32 @test10b(i32 undef) 238 ret i32 %call 239 240; CHECK-LABEL: define i32 @test10a( 241; CHECK-NEXT: entry: 242; CHECK-NEXT: %call = call i32 @test10b(i32 undef) 243; CHECK-NEXT: ret i32 %call 244} 245 246define internal i32 @test10b(i32 %x) nounwind { 247entry: 248 %r = and i32 %x, 1 249 ret i32 %r 250; CHECK-LABEL: define internal i32 @test10b( 251; CHECK-NEXT: entry: 252; CHECK-NEXT: %r = and i32 undef, 1 253; CHECK-NEXT: ret i32 %r 254} 255 256;;======================== test11 257 258define i64 @test11a() { 259 %xor = xor i64 undef, undef 260 ret i64 %xor 261; CHECK-LABEL: define i64 @test11a 262; CHECK-NEXT: %xor = xor i64 undef, undef 263; CHECK-NEXT: ret i64 %xor 264} 265 266define i64 @test11b() { 267 %call1 = call i64 @test11a() 268 %call2 = call i64 @llvm.ctpop.i64(i64 %call1) 269 ret i64 %call2 270; CHECK-LABEL: define i64 @test11b 271; CHECK-NEXT: [[call1:%.*]] = call i64 @test11a() 272; CHECK-NEXT: [[call2:%.*]] = call i64 @llvm.ctpop.i64(i64 [[call1]]) 273; CHECK-NEXT: ret i64 [[call2]] 274} 275 276declare i64 @llvm.ctpop.i64(i64) 277 278;;======================== test12 279;; Ensure that a struct as an arg to a potentially constant-foldable 280;; function does not crash SCCP (for now it'll just ignores it) 281 282define i1 @test12() { 283 %c = call i1 @llvm.is.constant.sl_i32i32s({i32, i32} {i32 -1, i32 32}) 284 ret i1 %c 285; CHECK-LABEL: define i1 @test12 286; CHECK: ret i1 %c 287} 288 289declare i1 @llvm.is.constant.sl_i32i32s({i32, i32} %a) 290