1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -ipsccp -S | FileCheck %s 3 4declare void @use(i1) 5 6@G = internal global i32 0 7 8define void @test1a() { 9; CHECK-LABEL: @test1a( 10; CHECK-NEXT: [[X:%.*]] = load i32, i32* @G 11; CHECK-NEXT: call void @use(i1 true) 12; CHECK-NEXT: call void @use(i1 true) 13; CHECK-NEXT: call void @use(i1 false) 14; CHECK-NEXT: call void @use(i1 false) 15; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20 16; CHECK-NEXT: call void @use(i1 [[C_1]]) 17; CHECK-NEXT: ret void 18; 19 %X = load i32, i32* @G 20 %t.1 = icmp ne i32 %X, 124 21 call void @use(i1 %t.1) 22 %t.2 = icmp ult i32 %X, 124 23 call void @use(i1 %t.2) 24 %f.1 = icmp eq i32 %X, 124 25 call void @use(i1 %f.1) 26 %f.2 = icmp ugt i32 %X, 123 27 call void @use(i1 %f.2) 28 %c.1 = icmp eq i32 %X, 20 29 call void @use(i1 %c.1) 30 ret void 31} 32 33define void @test1b(i1 %c) { 34; CHECK-LABEL: @test1b( 35; CHECK-NEXT: br i1 [[C:%.*]], label [[T:%.*]], label [[F:%.*]] 36; CHECK: T: 37; CHECK-NEXT: store i32 17, i32* @G 38; CHECK-NEXT: ret void 39; CHECK: F: 40; CHECK-NEXT: store i32 123, i32* @G 41; CHECK-NEXT: ret void 42; 43 br i1 %c, label %T, label %F 44T: 45 store i32 17, i32* @G 46 ret void 47F: 48 store i32 123, i32* @G 49 ret void 50} 51 52 53@H = internal global i32 0 54 55define void @test2a() { 56; CHECK-LABEL: @test2a( 57; CHECK-NEXT: [[X:%.*]] = load i32, i32* @H 58; CHECK-NEXT: call void @use(i1 true) 59; CHECK-NEXT: call void @use(i1 true) 60; CHECK-NEXT: call void @use(i1 false) 61; CHECK-NEXT: call void @use(i1 false) 62; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20 63; CHECK-NEXT: call void @use(i1 [[C_1]]) 64; CHECK-NEXT: ret void 65; 66 %X = load i32, i32* @H 67 %t.1 = icmp ne i32 %X, 124 68 call void @use(i1 %t.1) 69 %t.2 = icmp ult i32 %X, 124 70 call void @use(i1 %t.2) 71 %f.1 = icmp eq i32 %X, 124 72 call void @use(i1 %f.1) 73 %f.2 = icmp ugt i32 %X, 123 74 call void @use(i1 %f.2) 75 %c.1 = icmp eq i32 %X, 20 76 call void @use(i1 %c.1) 77 ret void 78} 79 80define void @test2b(i1 %c.1, i1 %c.2) { 81; CHECK-LABEL: @test2b( 82; CHECK-NEXT: br i1 [[C_1:%.*]], label [[T:%.*]], label [[F:%.*]] 83; CHECK: T: 84; CHECK-NEXT: br i1 [[C_2:%.*]], label [[T_1:%.*]], label [[F_1:%.*]] 85; CHECK: T.1: 86; CHECK-NEXT: store i32 17, i32* @H 87; CHECK-NEXT: ret void 88; CHECK: F.1: 89; CHECK-NEXT: store i32 20, i32* @H 90; CHECK-NEXT: ret void 91; CHECK: F: 92; CHECK-NEXT: store i32 123, i32* @H 93; CHECK-NEXT: ret void 94; 95 br i1 %c.1, label %T, label %F 96T: 97 br i1 %c.2, label %T.1, label %F.1 98 99T.1: 100 store i32 17, i32* @H 101 ret void 102 103F.1: 104 store i32 20, i32* @H 105 ret void 106 107F: 108 store i32 123, i32* @H 109 ret void 110} 111 112 113@I = internal global i32 0 114 115define void @test3a() { 116; CHECK-LABEL: @test3a( 117; CHECK-NEXT: [[X:%.*]] = load i32, i32* @I 118; CHECK-NEXT: call void @use(i1 true) 119; CHECK-NEXT: call void @use(i1 true) 120; CHECK-NEXT: call void @use(i1 false) 121; CHECK-NEXT: call void @use(i1 false) 122; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 20 123; CHECK-NEXT: call void @use(i1 [[C_1]]) 124; CHECK-NEXT: ret void 125; 126 %X = load i32, i32* @I 127 %t.1 = icmp ne i32 %X, 124 128 call void @use(i1 %t.1) 129 %t.2 = icmp ult i32 %X, 124 130 call void @use(i1 %t.2) 131 %f.1 = icmp eq i32 %X, 124 132 call void @use(i1 %f.1) 133 %f.2 = icmp ugt i32 %X, 123 134 call void @use(i1 %f.2) 135 %c.1 = icmp eq i32 %X, 20 136 call void @use(i1 %c.1) 137 ret void 138} 139 140define void @test3b(i1 %c.1, i1 %c.2) { 141; CHECK-LABEL: @test3b( 142; CHECK-NEXT: br i1 [[C_1:%.*]], label [[T:%.*]], label [[F:%.*]] 143; CHECK: T: 144; CHECK-NEXT: br label [[EXIT:%.*]] 145; CHECK: F: 146; CHECK-NEXT: br label [[EXIT]] 147; CHECK: exit: 148; CHECK-NEXT: [[P:%.*]] = phi i32 [ 17, [[T]] ], [ 123, [[F]] ] 149; CHECK-NEXT: store i32 [[P]], i32* @I 150; CHECK-NEXT: ret void 151; 152 br i1 %c.1, label %T, label %F 153 154T: 155 br label %exit 156 157F: 158 br label %exit 159 160exit: 161 %p = phi i32 [ 17, %T ], [ 123, %F ] 162 store i32 %p, i32* @I 163 ret void 164 165} 166 167; Make sure stored values are correctly updated to overdefined. 168@J = internal global i32 0 169 170define void @test4a() { 171; CHECK-LABEL: @test4a( 172; CHECK-NEXT: [[X:%.*]] = load i32, i32* @J 173; CHECK-NEXT: [[C_1:%.*]] = icmp ne i32 [[X]], 124 174; CHECK-NEXT: call void @use(i1 [[C_1]]) 175; CHECK-NEXT: [[C_2:%.*]] = icmp ult i32 [[X]], 124 176; CHECK-NEXT: call void @use(i1 [[C_2]]) 177; CHECK-NEXT: [[C_3:%.*]] = icmp eq i32 [[X]], 124 178; CHECK-NEXT: call void @use(i1 [[C_3]]) 179; CHECK-NEXT: [[C_4:%.*]] = icmp ugt i32 [[X]], 123 180; CHECK-NEXT: call void @use(i1 [[C_4]]) 181; CHECK-NEXT: [[C_5:%.*]] = icmp eq i32 [[X]], 20 182; CHECK-NEXT: call void @use(i1 [[C_5]]) 183; CHECK-NEXT: ret void 184; 185 %X = load i32, i32* @J 186 %c.1 = icmp ne i32 %X, 124 187 call void @use(i1 %c.1) 188 %c.2 = icmp ult i32 %X, 124 189 call void @use(i1 %c.2) 190 %c.3 = icmp eq i32 %X, 124 191 call void @use(i1 %c.3) 192 %c.4 = icmp ugt i32 %X, 123 193 call void @use(i1 %c.4) 194 %c.5 = icmp eq i32 %X, 20 195 call void @use(i1 %c.5) 196 ret void 197} 198 199define void @test4b(i1 %c.1, i1 %c.2, i32 %x) { 200; CHECK-LABEL: @test4b( 201; CHECK-NEXT: br i1 [[C_1:%.*]], label [[T:%.*]], label [[F:%.*]] 202; CHECK: T: 203; CHECK-NEXT: br i1 [[C_2:%.*]], label [[T_1:%.*]], label [[F_1:%.*]] 204; CHECK: T.1: 205; CHECK-NEXT: br label [[EXIT:%.*]] 206; CHECK: F.1: 207; CHECK-NEXT: br label [[EXIT]] 208; CHECK: F: 209; CHECK-NEXT: br label [[EXIT]] 210; CHECK: exit: 211; CHECK-NEXT: [[P:%.*]] = phi i32 [ 17, [[T_1]] ], [ [[X:%.*]], [[F_1]] ], [ 123, [[F]] ] 212; CHECK-NEXT: store i32 [[P]], i32* @J 213; CHECK-NEXT: ret void 214; 215 br i1 %c.1, label %T, label %F 216T: 217 br i1 %c.2, label %T.1, label %F.1 218 219T.1: 220 br label %exit 221 222F.1: 223 br label %exit 224 225F: 226 br label %exit 227 228exit: 229 %p = phi i32 [ 17, %T.1 ], [ %x, %F.1 ], [ 123, %F ] 230 store i32 %p, i32* @J 231 ret void 232} 233 234; Same as test1, but storing 4 different values. 235 236@K = internal global i32 501 237 238define void @test5a() { 239; CHECK-LABEL: @test5a( 240; CHECK-NEXT: [[X:%.*]] = load i32, i32* @K 241; CHECK-NEXT: call void @use(i1 true) 242; CHECK-NEXT: call void @use(i1 true) 243; CHECK-NEXT: call void @use(i1 false) 244; CHECK-NEXT: call void @use(i1 false) 245; CHECK-NEXT: [[C_1:%.*]] = icmp eq i32 [[X]], 510 246; CHECK-NEXT: call void @use(i1 [[C_1]]) 247; CHECK-NEXT: ret void 248; 249 %X = load i32, i32* @K 250 %t.1 = icmp ne i32 %X, 499 251 call void @use(i1 %t.1) 252 %t.2 = icmp ult i32 %X, 600 253 call void @use(i1 %t.2) 254 %f.1 = icmp eq i32 %X, 600 255 call void @use(i1 %f.1) 256 %f.2 = icmp ugt i32 %X, 600 257 call void @use(i1 %f.2) 258 %c.1 = icmp eq i32 %X, 510 259 call void @use(i1 %c.1) 260 ret void 261} 262 263define void @test5b(i1 %c.1, i1 %c.2) { 264; CHECK-LABEL: @test5b( 265; CHECK-NEXT: br i1 [[C_1:%.*]], label [[T_1:%.*]], label [[F_1:%.*]] 266; CHECK: T.1: 267; CHECK-NEXT: br i1 [[C_2:%.*]], label [[T_2:%.*]], label [[F_2:%.*]] 268; CHECK: T.2: 269; CHECK-NEXT: store i32 500, i32* @K 270; CHECK-NEXT: ret void 271; CHECK: F.2: 272; CHECK-NEXT: store i32 510, i32* @K 273; CHECK-NEXT: ret void 274; CHECK: F.1: 275; CHECK-NEXT: br i1 [[C_2]], label [[T_3:%.*]], label [[F_3:%.*]] 276; CHECK: T.3: 277; CHECK-NEXT: store i32 520, i32* @K 278; CHECK-NEXT: ret void 279; CHECK: F.3: 280; CHECK-NEXT: store i32 530, i32* @K 281; CHECK-NEXT: ret void 282; 283 br i1 %c.1, label %T.1, label %F.1 284 285T.1: 286 br i1 %c.2, label %T.2, label %F.2 287 288T.2: 289 store i32 500, i32* @K 290 ret void 291 292F.2: 293 store i32 510, i32* @K 294 ret void 295 296F.1: 297 br i1 %c.2, label %T.3, label %F.3 298 299T.3: 300 store i32 520, i32* @K 301 ret void 302 303F.3: 304 store i32 530, i32* @K 305 ret void 306} 307