341 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt -passes=instcombine -S < %s | FileCheck %s3 4declare void @use(i1)5 6; Check that we fold the condition of branches of the7; form: br <condition> dest1, dest2, where dest1 == dest2.8define i32 @test(i32 %x) {9; CHECK-LABEL: @test(10; CHECK-NEXT: entry:11; CHECK-NEXT: br i1 false, label [[MERGE:%.*]], label [[MERGE]]12; CHECK: merge:13; CHECK-NEXT: ret i32 [[X:%.*]]14;15entry:16 %cmp = icmp ult i32 %x, 717 br i1 %cmp, label %merge, label %merge18merge:19 ret i32 %x20}21 22@global = global i8 023 24define i32 @pat(i32 %x) {25; CHECK-LABEL: @pat(26; CHECK-NEXT: br i1 false, label [[PATATINO:%.*]], label [[PATATINO]]27; CHECK: patatino:28; CHECK-NEXT: ret i32 [[X:%.*]]29;30 %y = icmp eq i32 27, ptrtoint(ptr @global to i32)31 br i1 %y, label %patatino, label %patatino32patatino:33 ret i32 %x34}35 36define i1 @test01(i1 %cond) {37; CHECK-LABEL: @test01(38; CHECK-NEXT: entry:39; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]]40; CHECK: if.true.1:41; CHECK-NEXT: br label [[MERGE_1:%.*]]42; CHECK: if.false.1:43; CHECK-NEXT: br label [[MERGE_1]]44; CHECK: merge.1:45; CHECK-NEXT: br i1 [[COND]], label [[IF_TRUE_2:%.*]], label [[IF_FALSE_2:%.*]]46; CHECK: if.true.2:47; CHECK-NEXT: br label [[MERGE_2:%.*]]48; CHECK: if.false.2:49; CHECK-NEXT: br label [[MERGE_2]]50; CHECK: merge.2:51; CHECK-NEXT: ret i1 [[COND]]52;53entry:54 br i1 %cond, label %if.true.1, label %if.false.155 56if.true.1:57 br label %merge.158 59if.false.1:60 br label %merge.161 62merge.1:63 %merge.cond.1 = phi i1 [true, %if.true.1], [false, %if.false.1]64 br i1 %merge.cond.1, label %if.true.2, label %if.false.265 66if.true.2:67 br label %merge.268 69if.false.2:70 br label %merge.271 72merge.2:73 %merge.cond.2 = phi i1 [true, %if.true.2], [false, %if.false.2]74 ret i1 %merge.cond.275}76 77define i1 @test02(i1 %cond) {78; CHECK-LABEL: @test02(79; CHECK-NEXT: entry:80; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_TRUE_1:%.*]], label [[IF_FALSE_1:%.*]]81; CHECK: if.true.1:82; CHECK-NEXT: br label [[MERGE_1:%.*]]83; CHECK: if.false.1:84; CHECK-NEXT: br label [[MERGE_1]]85; CHECK: merge.1:86; CHECK-NEXT: br i1 [[COND]], label [[IF_FALSE_2:%.*]], label [[IF_TRUE_2:%.*]]87; CHECK: if.true.2:88; CHECK-NEXT: br label [[MERGE_2:%.*]]89; CHECK: if.false.2:90; CHECK-NEXT: br label [[MERGE_2]]91; CHECK: merge.2:92; CHECK-NEXT: ret i1 [[COND]]93;94entry:95 br i1 %cond, label %if.true.1, label %if.false.196 97if.true.1:98 br label %merge.199 100if.false.1:101 br label %merge.1102 103merge.1:104 %merge.cond.1 = phi i1 [false, %if.true.1], [true, %if.false.1]105 br i1 %merge.cond.1, label %if.true.2, label %if.false.2106 107if.true.2:108 br label %merge.2109 110if.false.2:111 br label %merge.2112 113merge.2:114 %merge.cond.2 = phi i1 [false, %if.true.2], [true, %if.false.2]115 ret i1 %merge.cond.2116}117 118; if (x && !y) ret 42; ret 3 --> if (!x || y) ret 3; ret 42119 120define i32 @logical_and_not(i1 %x, i1 %y) {121; CHECK-LABEL: @logical_and_not(122; CHECK-NEXT: entry:123; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true124; CHECK-NEXT: [[TMP0:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y:%.*]]125; CHECK-NEXT: br i1 [[TMP0]], label [[F:%.*]], label [[T:%.*]]126; CHECK: t:127; CHECK-NEXT: ret i32 42128; CHECK: f:129; CHECK-NEXT: ret i32 3130;131entry:132 %noty = xor i1 %y, true133 %and = select i1 %x, i1 %noty, i1 false134 br i1 %and, label %t, label %f135 136t:137 ret i32 42138 139f:140 ret i32 3141}142 143; if (x && y || !x) ret 3; ret 42 --> if (!x || y) ret 3; ret 42144 145define i32 @logical_and_or(i1 %x, i1 %y) {146; CHECK-LABEL: @logical_and_or(147; CHECK-NEXT: entry:148; CHECK-NEXT: [[NOT_X:%.*]] = xor i1 [[X:%.*]], true149; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOT_X]], i1 true, i1 [[Y:%.*]]150; CHECK-NEXT: br i1 [[AND]], label [[F:%.*]], label [[T:%.*]]151; CHECK: t:152; CHECK-NEXT: ret i32 42153; CHECK: f:154; CHECK-NEXT: ret i32 3155;156entry:157 %and = select i1 %x, i1 %y, i1 true158 br i1 %and, label %f, label %t159 160t:161 ret i32 42162 163f:164 ret i32 3165}166 167; if (!x || y) ret 3; ret 42168 169define i32 @logical_or_not(i1 %x, i1 %y) {170; CHECK-LABEL: @logical_or_not(171; CHECK-NEXT: entry:172; CHECK-NEXT: [[NOTX:%.*]] = xor i1 [[X:%.*]], true173; CHECK-NEXT: [[AND:%.*]] = select i1 [[NOTX]], i1 true, i1 [[Y:%.*]]174; CHECK-NEXT: br i1 [[AND]], label [[F:%.*]], label [[T:%.*]]175; CHECK: t:176; CHECK-NEXT: ret i32 42177; CHECK: f:178; CHECK-NEXT: ret i32 3179;180entry:181 %notx = xor i1 %x, true182 %and = select i1 %notx, i1 true, i1 %y183 br i1 %and, label %f, label %t184 185t:186 ret i32 42187 188f:189 ret i32 3190}191 192; negative test193 194define i32 @logical_and_not_use1(i1 %x, i1 %y) {195; CHECK-LABEL: @logical_and_not_use1(196; CHECK-NEXT: entry:197; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true198; CHECK-NEXT: call void @use(i1 [[NOTY]])199; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false200; CHECK-NEXT: br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]201; CHECK: t:202; CHECK-NEXT: ret i32 42203; CHECK: f:204; CHECK-NEXT: ret i32 3205;206entry:207 %noty = xor i1 %y, true208 call void @use(i1 %noty)209 %and = select i1 %x, i1 %noty, i1 false210 br i1 %and, label %t, label %f211 212t:213 ret i32 42214 215f:216 ret i32 3217}218 219; negative test220 221define i32 @logical_and_not_use2(i1 %x, i1 %y) {222; CHECK-LABEL: @logical_and_not_use2(223; CHECK-NEXT: entry:224; CHECK-NEXT: [[NOTY:%.*]] = xor i1 [[Y:%.*]], true225; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[NOTY]], i1 false226; CHECK-NEXT: call void @use(i1 [[AND]])227; CHECK-NEXT: br i1 [[AND]], label [[T:%.*]], label [[F:%.*]]228; CHECK: t:229; CHECK-NEXT: ret i32 42230; CHECK: f:231; CHECK-NEXT: ret i32 3232;233entry:234 %noty = xor i1 %y, true235 %and = select i1 %x, i1 %noty, i1 false236 call void @use(i1 %and)237 br i1 %and, label %t, label %f238 239t:240 ret i32 42241 242f:243 ret i32 3244}245 246define i32 @dom_true(i1 %cmp) {247; CHECK-LABEL: @dom_true(248; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]249; CHECK: if.then:250; CHECK-NEXT: ret i32 1251; CHECK: if.else:252; CHECK-NEXT: ret i32 0253;254 br i1 %cmp, label %if.then, label %if.else255 256if.then:257 %zext = zext i1 %cmp to i32258 ret i32 %zext259 260if.else:261 ret i32 0262}263 264define i32 @dom_false(i1 %cmp) {265; CHECK-LABEL: @dom_false(266; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_ELSE:%.*]], label [[IF_THEN:%.*]]267; CHECK: if.then:268; CHECK-NEXT: ret i32 0269; CHECK: if.else:270; CHECK-NEXT: ret i32 0271;272 br i1 %cmp, label %if.else, label %if.then273 274if.then:275 %zext = zext i1 %cmp to i32276 ret i32 %zext277 278if.else:279 ret i32 0280}281 282define i32 @dom_true_phi(i1 %cmp) {283; CHECK-LABEL: @dom_true_phi(284; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]285; CHECK: if.then:286; CHECK-NEXT: br label [[IF_END:%.*]]287; CHECK: if.else:288; CHECK-NEXT: br label [[IF_END]]289; CHECK: if.end:290; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32291; CHECK-NEXT: ret i32 [[ZEXT]]292;293 br i1 %cmp, label %if.then, label %if.else294 295if.then:296 br label %if.end297 298if.else:299 br label %if.end300 301if.end:302 %phi = phi i1 [ true, %if.then ], [ %cmp, %if.else ]303 %zext = zext i1 %phi to i32304 ret i32 %zext305}306 307; Negative tests308 309define i32 @same_dest(i1 %cmp) {310; CHECK-LABEL: @same_dest(311; CHECK-NEXT: br i1 false, label [[IF_THEN:%.*]], label [[IF_THEN]]312; CHECK: if.then:313; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP:%.*]] to i32314; CHECK-NEXT: ret i32 [[ZEXT]]315;316 br i1 %cmp, label %if.then, label %if.then317 318if.then:319 %zext = zext i1 %cmp to i32320 ret i32 %zext321}322 323define i32 @not_dom(i1 %cmp) {324; CHECK-LABEL: @not_dom(325; CHECK-NEXT: br i1 [[CMP:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]326; CHECK: if.then:327; CHECK-NEXT: br label [[IF_ELSE]]328; CHECK: if.else:329; CHECK-NEXT: [[ZEXT:%.*]] = zext i1 [[CMP]] to i32330; CHECK-NEXT: ret i32 [[ZEXT]]331;332 br i1 %cmp, label %if.then, label %if.else333 334if.then:335 br label %if.else336 337if.else:338 %zext = zext i1 %cmp to i32339 ret i32 %zext340}341