1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=newgvn -S | FileCheck %s 3 4 5declare void @foo(i1) 6declare void @bar(i32) 7 8define void @test_and(i32 %x, i32 %y) { 9; CHECK-LABEL: @test_and( 10; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0 11; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 12; CHECK-NEXT: [[Z:%.*]] = and i1 [[XZ]], [[YZ]] 13; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]] 14; CHECK: both_zero: 15; CHECK-NEXT: call void @foo(i1 true) 16; CHECK-NEXT: call void @foo(i1 true) 17; CHECK-NEXT: call void @bar(i32 0) 18; CHECK-NEXT: call void @bar(i32 0) 19; CHECK-NEXT: ret void 20; CHECK: nope: 21; CHECK-NEXT: call void @foo(i1 false) 22; CHECK-NEXT: ret void 23; 24 %xz = icmp eq i32 %x, 0 25 %yz = icmp eq i32 %y, 0 26 %z = and i1 %xz, %yz 27 br i1 %z, label %both_zero, label %nope 28both_zero: 29 call void @foo(i1 %xz) 30 call void @foo(i1 %yz) 31 call void @bar(i32 %x) 32 call void @bar(i32 %y) 33 ret void 34nope: 35 call void @foo(i1 %z) 36 ret void 37} 38 39define void @test_and_logical(i32 %x, i32 %y) { 40; CHECK-LABEL: @test_and_logical( 41; CHECK-NEXT: [[XZ:%.*]] = icmp eq i32 [[X:%.*]], 0 42; CHECK-NEXT: [[YZ:%.*]] = icmp eq i32 [[Y:%.*]], 0 43; CHECK-NEXT: [[Z:%.*]] = select i1 [[XZ]], i1 [[YZ]], i1 false 44; CHECK-NEXT: br i1 [[Z]], label [[BOTH_ZERO:%.*]], label [[NOPE:%.*]] 45; CHECK: both_zero: 46; CHECK-NEXT: call void @foo(i1 true) 47; CHECK-NEXT: call void @foo(i1 true) 48; CHECK-NEXT: call void @bar(i32 0) 49; CHECK-NEXT: call void @bar(i32 0) 50; CHECK-NEXT: ret void 51; CHECK: nope: 52; CHECK-NEXT: call void @foo(i1 false) 53; CHECK-NEXT: ret void 54; 55 %xz = icmp eq i32 %x, 0 56 %yz = icmp eq i32 %y, 0 57 %z = select i1 %xz, i1 %yz, i1 false 58 br i1 %z, label %both_zero, label %nope 59both_zero: 60 call void @foo(i1 %xz) 61 call void @foo(i1 %yz) 62 call void @bar(i32 %x) 63 call void @bar(i32 %y) 64 ret void 65nope: 66 call void @foo(i1 %z) 67 ret void 68} 69 70define void @test_or(i32 %x, i32 %y) { 71; CHECK-LABEL: @test_or( 72; CHECK-NEXT: [[XZ:%.*]] = icmp ne i32 [[X:%.*]], 0 73; CHECK-NEXT: [[YZ:%.*]] = icmp ne i32 [[Y:%.*]], 0 74; CHECK-NEXT: [[Z:%.*]] = or i1 [[XZ]], [[YZ]] 75; CHECK-NEXT: br i1 [[Z]], label [[NOPE:%.*]], label [[BOTH_ZERO:%.*]] 76; CHECK: both_zero: 77; CHECK-NEXT: call void @foo(i1 false) 78; CHECK-NEXT: call void @foo(i1 false) 79; CHECK-NEXT: call void @bar(i32 0) 80; CHECK-NEXT: call void @bar(i32 0) 81; CHECK-NEXT: ret void 82; CHECK: nope: 83; CHECK-NEXT: call void @foo(i1 true) 84; CHECK-NEXT: ret void 85; 86 %xz = icmp ne i32 %x, 0 87 %yz = icmp ne i32 %y, 0 88 %z = or i1 %xz, %yz 89 br i1 %z, label %nope, label %both_zero 90both_zero: 91 call void @foo(i1 %xz) 92 call void @foo(i1 %yz) 93 call void @bar(i32 %x) 94 call void @bar(i32 %y) 95 ret void 96nope: 97 call void @foo(i1 %z) 98 ret void 99} 100 101define void @test_or_logical(i32 %x, i32 %y) { 102; CHECK-LABEL: @test_or_logical( 103; CHECK-NEXT: [[XZ:%.*]] = icmp ne i32 [[X:%.*]], 0 104; CHECK-NEXT: [[YZ:%.*]] = icmp ne i32 [[Y:%.*]], 0 105; CHECK-NEXT: [[Z:%.*]] = select i1 [[XZ]], i1 true, i1 [[YZ]] 106; CHECK-NEXT: br i1 [[Z]], label [[NOPE:%.*]], label [[BOTH_ZERO:%.*]] 107; CHECK: both_zero: 108; CHECK-NEXT: call void @foo(i1 false) 109; CHECK-NEXT: call void @foo(i1 false) 110; CHECK-NEXT: call void @bar(i32 0) 111; CHECK-NEXT: call void @bar(i32 0) 112; CHECK-NEXT: ret void 113; CHECK: nope: 114; CHECK-NEXT: call void @foo(i1 true) 115; CHECK-NEXT: ret void 116; 117 %xz = icmp ne i32 %x, 0 118 %yz = icmp ne i32 %y, 0 119 %z = select i1 %xz, i1 true, i1 %yz 120 br i1 %z, label %nope, label %both_zero 121both_zero: 122 call void @foo(i1 %xz) 123 call void @foo(i1 %yz) 124 call void @bar(i32 %x) 125 call void @bar(i32 %y) 126 ret void 127nope: 128 call void @foo(i1 %z) 129 ret void 130} 131 132define void @test4(i1 %b, i32 %x) { 133; CHECK-LABEL: @test4( 134; CHECK-NEXT: br i1 [[B:%.*]], label [[SW:%.*]], label [[CASE3:%.*]] 135; CHECK: sw: 136; CHECK-NEXT: switch i32 [[X:%.*]], label [[DEFAULT:%.*]] [ 137; CHECK-NEXT: i32 0, label [[CASE0:%.*]] 138; CHECK-NEXT: i32 1, label [[CASE1:%.*]] 139; CHECK-NEXT: i32 2, label [[CASE0]] 140; CHECK-NEXT: i32 3, label [[CASE3]] 141; CHECK-NEXT: i32 4, label [[DEFAULT]] 142; CHECK-NEXT: ] 143; CHECK: default: 144; CHECK-NEXT: call void @bar(i32 [[X]]) 145; CHECK-NEXT: ret void 146; CHECK: case0: 147; CHECK-NEXT: call void @bar(i32 [[X]]) 148; CHECK-NEXT: ret void 149; CHECK: case1: 150; CHECK-NEXT: call void @bar(i32 1) 151; CHECK-NEXT: ret void 152; CHECK: case3: 153; CHECK-NEXT: call void @bar(i32 [[X]]) 154; CHECK-NEXT: ret void 155; 156 br i1 %b, label %sw, label %case3 157sw: 158 switch i32 %x, label %default [ 159 i32 0, label %case0 160 i32 1, label %case1 161 i32 2, label %case0 162 i32 3, label %case3 163 i32 4, label %default 164 ] 165default: 166 call void @bar(i32 %x) 167 ret void 168case0: 169 call void @bar(i32 %x) 170 ret void 171case1: 172 call void @bar(i32 %x) 173 ret void 174case3: 175 call void @bar(i32 %x) 176 ret void 177} 178 179define i1 @test5(i32 %x, i32 %y) { 180; CHECK-LABEL: @test5( 181; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]] 182; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 183; CHECK: same: 184; CHECK-NEXT: ret i1 false 185; CHECK: different: 186; CHECK-NEXT: ret i1 false 187; 188 %cmp = icmp eq i32 %x, %y 189 br i1 %cmp, label %same, label %different 190 191same: 192 %cmp2 = icmp ne i32 %x, %y 193 ret i1 %cmp2 194 195different: 196 %cmp3 = icmp eq i32 %x, %y 197 ret i1 %cmp3 198} 199 200 201define i1 @test7(i32 %x, i32 %y) { 202; CHECK-LABEL: @test7( 203; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], [[Y:%.*]] 204; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 205; CHECK: same: 206; CHECK-NEXT: ret i1 false 207; CHECK: different: 208; CHECK-NEXT: ret i1 false 209; 210 %cmp = icmp sgt i32 %x, %y 211 br i1 %cmp, label %same, label %different 212 213same: 214 %cmp2 = icmp sle i32 %x, %y 215 ret i1 %cmp2 216 217different: 218 %cmp3 = icmp sgt i32 %x, %y 219 ret i1 %cmp3 220} 221 222define i1 @test7_fp(float %x, float %y) { 223; CHECK-LABEL: @test7_fp( 224; CHECK-NEXT: [[CMP:%.*]] = fcmp ogt float [[X:%.*]], [[Y:%.*]] 225; CHECK-NEXT: br i1 [[CMP]], label [[SAME:%.*]], label [[DIFFERENT:%.*]] 226; CHECK: same: 227; CHECK-NEXT: ret i1 false 228; CHECK: different: 229; CHECK-NEXT: ret i1 false 230; 231 %cmp = fcmp ogt float %x, %y 232 br i1 %cmp, label %same, label %different 233 234same: 235 %cmp2 = fcmp ule float %x, %y 236 ret i1 %cmp2 237 238different: 239 %cmp3 = fcmp ogt float %x, %y 240 ret i1 %cmp3 241} 242 243; PR1768 244define i32 @test9(i32 %i, i32 %j) { 245; CHECK-LABEL: @test9( 246; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]] 247; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]] 248; CHECK: cond_true: 249; CHECK-NEXT: ret i32 0 250; CHECK: ret: 251; CHECK-NEXT: ret i32 5 252; 253 %cmp = icmp eq i32 %i, %j 254 br i1 %cmp, label %cond_true, label %ret 255 256cond_true: 257 %diff = sub i32 %i, %j 258 ret i32 %diff 259 260ret: 261 ret i32 5 262} 263 264; PR1768 265define i32 @test10(i32 %j, i32 %i) { 266; CHECK-LABEL: @test10( 267; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[I:%.*]], [[J:%.*]] 268; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[RET:%.*]] 269; CHECK: cond_true: 270; CHECK-NEXT: ret i32 0 271; CHECK: ret: 272; CHECK-NEXT: ret i32 5 273; 274 %cmp = icmp eq i32 %i, %j 275 br i1 %cmp, label %cond_true, label %ret 276 277cond_true: 278 %diff = sub i32 %i, %j 279 ret i32 %diff 280 281ret: 282 ret i32 5 283} 284 285declare i32 @yogibar() 286 287define i32 @test11(i32 %x) { 288; CHECK-LABEL: @test11( 289; CHECK-NEXT: [[V0:%.*]] = call i32 @yogibar() 290; CHECK-NEXT: [[V1:%.*]] = call i32 @yogibar() 291; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[V0]], [[V1]] 292; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[NEXT:%.*]] 293; CHECK: cond_true: 294; CHECK-NEXT: ret i32 [[V0]] 295; CHECK: next: 296; CHECK-NEXT: [[CMP2:%.*]] = icmp eq i32 [[X:%.*]], [[V0]] 297; CHECK-NEXT: br i1 [[CMP2]], label [[COND_TRUE2:%.*]], label [[NEXT2:%.*]] 298; CHECK: cond_true2: 299; CHECK-NEXT: ret i32 [[X]] 300; CHECK: next2: 301; CHECK-NEXT: ret i32 0 302; 303 %v0 = call i32 @yogibar() 304 %v1 = call i32 @yogibar() 305 %cmp = icmp eq i32 %v0, %v1 306 br i1 %cmp, label %cond_true, label %next 307 308cond_true: 309 ret i32 %v1 310 311next: 312 %cmp2 = icmp eq i32 %x, %v0 313 br i1 %cmp2, label %cond_true2, label %next2 314 315cond_true2: 316 ret i32 %v0 317 318next2: 319 ret i32 0 320} 321 322define i32 @test12(i32 %x) { 323; CHECK-LABEL: @test12( 324; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X:%.*]], 0 325; CHECK-NEXT: br i1 [[CMP]], label [[COND_TRUE:%.*]], label [[COND_FALSE:%.*]] 326; CHECK: cond_true: 327; CHECK-NEXT: br label [[RET:%.*]] 328; CHECK: cond_false: 329; CHECK-NEXT: br label [[RET]] 330; CHECK: ret: 331; CHECK-NEXT: [[RES:%.*]] = phi i32 [ 0, [[COND_TRUE]] ], [ [[X]], [[COND_FALSE]] ] 332; CHECK-NEXT: ret i32 [[RES]] 333; 334 %cmp = icmp eq i32 %x, 0 335 br i1 %cmp, label %cond_true, label %cond_false 336 337cond_true: 338 br label %ret 339 340cond_false: 341 br label %ret 342 343ret: 344 %res = phi i32 [ %x, %cond_true ], [ %x, %cond_false ] 345 ret i32 %res 346} 347