810 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --check-globals2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare i1 @gen1()5 6;.7; CHECK: @glb = global i8 08;.9define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) {10; CHECK-LABEL: @cond_eq_and(11; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[C:%.*]]12; CHECK-NEXT: [[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]]13; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 [[LHS]], i1 false14; CHECK-NEXT: ret i1 [[RES]]15;16 %cond = icmp eq i8 %X, %C17 %lhs = icmp ult i8 %X, %Y18 %res = select i1 %cond, i1 %lhs, i1 false19 ret i1 %res20}21 22define i1 @cond_eq_and_const(i8 %X, i8 %Y) !prof !0 {23; CHECK-LABEL: @cond_eq_and_const(24; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], 1025; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 1026; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 [[TMP1]], i1 false, !prof [[PROF1:![0-9]+]]27; CHECK-NEXT: ret i1 [[RES]]28;29 %cond = icmp eq i8 %X, 1030 %lhs = icmp ult i8 %X, %Y31 %res = select i1 %cond, i1 %lhs, i1 false, !prof !132 ret i1 %res33}34 35define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) {36; CHECK-LABEL: @cond_eq_or(37; CHECK-NEXT: [[COND:%.*]] = icmp ne i8 [[X:%.*]], [[C:%.*]]38; CHECK-NEXT: [[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]]39; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[LHS]]40; CHECK-NEXT: ret i1 [[RES]]41;42 %cond = icmp ne i8 %X, %C43 %lhs = icmp ult i8 %X, %Y44 %res = select i1 %cond, i1 true, i1 %lhs45 ret i1 %res46}47 48define i1 @cond_eq_or_const(i8 %X, i8 %Y) !prof !0 {49; CHECK-LABEL: @cond_eq_or_const(50; CHECK-NEXT: [[COND:%.*]] = icmp ne i8 [[X:%.*]], 1051; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 1052; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[TMP1]], !prof [[PROF1]]53; CHECK-NEXT: ret i1 [[RES]]54;55 %cond = icmp ne i8 %X, 1056 %lhs = icmp ult i8 %X, %Y57 %res = select i1 %cond, i1 true, i1 %lhs, !prof !158 ret i1 %res59}60 61define i1 @xor_and(i1 %c, i32 %X, i32 %Y) !prof !0 {62; CHECK-LABEL: @xor_and(63; CHECK-NEXT: [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]64; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true65; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[COMP]], !prof [[PROF2:![0-9]+]]66; CHECK-NEXT: ret i1 [[SEL]]67;68 %comp = icmp ult i32 %X, %Y69 %sel = select i1 %c, i1 %comp, i1 false, !prof !170 %res = xor i1 %sel, true71 ret i1 %res72}73 74define <2 x i1> @xor_and2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {75; CHECK-LABEL: @xor_and2(76; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]77; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 false, i1 true>78; CHECK-NEXT: ret <2 x i1> [[SEL]]79;80 %comp = icmp ult <2 x i32> %X, %Y81 %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 true, i1 false>82 %res = xor <2 x i1> %sel, <i1 true, i1 true>83 ret <2 x i1> %res84}85 86@glb = global i8 087 88define <2 x i1> @xor_and3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {89; CHECK-LABEL: @xor_and3(90; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]91; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 xor (i1 ptrtoint (ptr @glb to i1), i1 true), i1 true>92; CHECK-NEXT: ret <2 x i1> [[SEL]]93;94 %comp = icmp ult <2 x i32> %X, %Y95 %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 ptrtoint (ptr @glb to i1), i1 false>96 %res = xor <2 x i1> %sel, <i1 true, i1 true>97 ret <2 x i1> %res98}99 100define i1 @xor_or(i1 %c, i32 %X, i32 %Y) !prof !0 {101; CHECK-LABEL: @xor_or(102; CHECK-NEXT: [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]]103; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true104; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C]], i1 [[COMP]], i1 false, !prof [[PROF2]]105; CHECK-NEXT: ret i1 [[SEL]]106;107 %comp = icmp ult i32 %X, %Y108 %sel = select i1 %c, i1 true, i1 %comp, !prof !1109 %res = xor i1 %sel, true110 ret i1 %res111}112 113define <2 x i1> @xor_or2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {114; CHECK-LABEL: @xor_or2(115; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]116; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 false, i1 true>, <2 x i1> [[COMP]]117; CHECK-NEXT: ret <2 x i1> [[SEL]]118;119 %comp = icmp ult <2 x i32> %X, %Y120 %sel = select <2 x i1> %c, <2 x i1> <i1 true, i1 false>, <2 x i1> %comp121 %res = xor <2 x i1> %sel, <i1 true, i1 true>122 ret <2 x i1> %res123}124 125define <2 x i1> @xor_or3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) {126; CHECK-LABEL: @xor_or3(127; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]]128; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 xor (i1 ptrtoint (ptr @glb to i1), i1 true), i1 true>, <2 x i1> [[COMP]]129; CHECK-NEXT: ret <2 x i1> [[SEL]]130;131 %comp = icmp ult <2 x i32> %X, %Y132 %sel = select <2 x i1> %c, <2 x i1> <i1 ptrtoint (ptr @glb to i1), i1 false>, <2 x i1> %comp133 %res = xor <2 x i1> %sel, <i1 true, i1 true>134 ret <2 x i1> %res135}136 137define i1 @and_orn_cmp_1_logical(i32 %a, i32 %b, i1 %y) {138; CHECK-LABEL: @and_orn_cmp_1_logical(139; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]140; CHECK-NEXT: [[AND:%.*]] = select i1 [[X]], i1 [[Y:%.*]], i1 false141; CHECK-NEXT: ret i1 [[AND]]142;143 %x = icmp sgt i32 %a, %b144 %x_inv = icmp sle i32 %a, %b145 %or = select i1 %y, i1 true, i1 %x_inv146 %and = select i1 %x, i1 %or, i1 false147 ret i1 %and148}149 150; TODO: This should fold the same way as the next test.151 152define i1 @and_orn_cmp_1_partial_logical(i32 %a, i32 %b, i1 %y) {153; CHECK-LABEL: @and_orn_cmp_1_partial_logical(154; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]155; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i32 [[A]], [[B]]156; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y:%.*]]157; CHECK-NEXT: [[AND:%.*]] = select i1 [[X]], i1 [[OR]], i1 false158; CHECK-NEXT: ret i1 [[AND]]159;160 %x = icmp sgt i32 %a, %b161 %x_inv = icmp sle i32 %a, %b162 %or = or i1 %x_inv, %y163 %and = select i1 %x, i1 %or, i1 false164 ret i1 %and165}166 167define i1 @and_orn_cmp_1_partial_logical_commute(i32 %a, i32 %b) {168; CHECK-LABEL: @and_orn_cmp_1_partial_logical_commute(169; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1()170; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]]171; CHECK-NEXT: [[AND:%.*]] = select i1 [[X]], i1 [[Y]], i1 false172; CHECK-NEXT: ret i1 [[AND]]173;174 %y = call i1 @gen1() ; thwart complexity-based canonicalization175 %x = icmp sgt i32 %a, %b176 %x_inv = icmp sle i32 %a, %b177 %or = or i1 %y, %x_inv178 %and = select i1 %x, i1 %or, i1 false179 ret i1 %and180}181 182; TODO: This does not require poison-safe (select) logical-and.183 184define i1 @andn_or_cmp_2_logical(i16 %a, i16 %b, i1 %y) {185; CHECK-LABEL: @andn_or_cmp_2_logical(186; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]187; CHECK-NEXT: [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X_INV]], i1 false188; CHECK-NEXT: ret i1 [[AND]]189;190 %x = icmp sge i16 %a, %b191 %x_inv = icmp slt i16 %a, %b192 %or = select i1 %y, i1 true, i1 %x193 %and = select i1 %or, i1 %x_inv, i1 false194 ret i1 %and195}196 197define i1 @andn_or_cmp_2_partial_logical(i16 %a, i16 %b, i1 %y) {198; CHECK-LABEL: @andn_or_cmp_2_partial_logical(199; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]200; CHECK-NEXT: [[AND:%.*]] = and i1 [[Y:%.*]], [[X_INV]]201; CHECK-NEXT: ret i1 [[AND]]202;203 %x = icmp sge i16 %a, %b204 %x_inv = icmp slt i16 %a, %b205 %or = or i1 %x, %y206 %and = select i1 %or, i1 %x_inv, i1 false207 ret i1 %and208}209 210define i1 @andn_or_cmp_2_partial_logical_commute(i16 %a, i16 %b) {211; CHECK-LABEL: @andn_or_cmp_2_partial_logical_commute(212; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1()213; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]214; CHECK-NEXT: [[AND:%.*]] = and i1 [[Y]], [[X_INV]]215; CHECK-NEXT: ret i1 [[AND]]216;217 %y = call i1 @gen1() ; thwart complexity-based canonicalization218 %x = icmp sge i16 %a, %b219 %x_inv = icmp slt i16 %a, %b220 %or = or i1 %y, %x221 %and = select i1 %or, i1 %x_inv, i1 false222 ret i1 %and223}224 225; PR58552 - this would crash trying to replace non-matching types226 227define <2 x i1> @not_logical_or(i1 %b, <2 x i32> %a) {228; CHECK-LABEL: @not_logical_or(229; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3)230; CHECK-NEXT: [[IMPLIED:%.*]] = icmp slt <2 x i32> [[A]], splat (i32 -1)231; CHECK-NEXT: [[OR:%.*]] = select i1 [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[IMPLIED]]232; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[COND]], <2 x i1> [[OR]], <2 x i1> zeroinitializer233; CHECK-NEXT: ret <2 x i1> [[AND]]234;235 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3>236 %implied = icmp slt <2 x i32> %a, <i32 -1, i32 -1>237 %or = select i1 %b, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied238 %and = select <2 x i1> %cond, <2 x i1> %or, <2 x i1> zeroinitializer239 ret <2 x i1> %and240}241 242; This could reduce, but we do not match select-of-vectors with scalar condition as logical-or.243 244define <2 x i1> @not_logical_or2(i1 %b, <2 x i32> %a) {245; CHECK-LABEL: @not_logical_or2(246; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3)247; CHECK-NEXT: [[IMPLIED:%.*]] = icmp slt <2 x i32> [[A]], splat (i32 -1)248; CHECK-NEXT: [[OR:%.*]] = select i1 [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[IMPLIED]]249; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[OR]], <2 x i1> [[COND]], <2 x i1> zeroinitializer250; CHECK-NEXT: ret <2 x i1> [[AND]]251;252 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3>253 %implied = icmp slt <2 x i32> %a, <i32 -1, i32 -1>254 %or = select i1 %b, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied255 %and = select <2 x i1> %or, <2 x i1> %cond, <2 x i1> zeroinitializer256 ret <2 x i1> %and257}258 259define i1 @bools_logical_commute0(i1 %a, i1 %b, i1 %c) !prof !0 {260; CHECK-LABEL: @bools_logical_commute0(261; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF2]]262; CHECK-NEXT: ret i1 [[OR]]263;264 %not = xor i1 %c, -1265 %and1 = select i1 %not, i1 %a, i1 false, !prof!1266 %and2 = select i1 %c, i1 %b, i1 false, !prof !2267 %or = select i1 %and1, i1 true, i1 %and2, !prof !3268 ret i1 %or269}270 271define i1 @bools_logical_commute0_and1(i1 %a, i1 %b, i1 %c) !prof !0 {272; CHECK-LABEL: @bools_logical_commute0_and1(273; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF1]]274; CHECK-NEXT: ret i1 [[OR]]275;276 %not = xor i1 %c, -1277 %and1 = and i1 %not, %a278 %and2 = select i1 %c, i1 %b, i1 false, !prof !1279 %or = select i1 %and1, i1 true, i1 %and2, !prof !2280 ret i1 %or281}282 283define i1 @bools_logical_commute0_and2(i1 %a, i1 %b, i1 %c) {284; CHECK-LABEL: @bools_logical_commute0_and2(285; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]286; CHECK-NEXT: ret i1 [[OR]]287;288 %not = xor i1 %c, -1289 %and1 = select i1 %not, i1 %a, i1 false290 %and2 = and i1 %c, %b291 %or = select i1 %and1, i1 true, i1 %and2292 ret i1 %or293}294 295define i1 @bools_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) !prof !0 {296; CHECK-LABEL: @bools_logical_commute0_and1_and2(297; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]], !prof [[PROF3:![0-9]+]]298; CHECK-NEXT: ret i1 [[OR]]299;300 %not = xor i1 %c, -1301 %and1 = and i1 %not, %a302 %and2 = and i1 %c, %b303 %or = select i1 %and1, i1 true, i1 %and2, !prof !1304 ret i1 %or305}306 307define i1 @bools_logical_commute1(i1 %a, i1 %b, i1 %c) {308; CHECK-LABEL: @bools_logical_commute1(309; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]310; CHECK-NEXT: ret i1 [[OR]]311;312 %not = xor i1 %c, -1313 %and1 = select i1 %a, i1 %not, i1 false314 %and2 = select i1 %c, i1 %b, i1 false315 %or = select i1 %and1, i1 true, i1 %and2316 ret i1 %or317}318 319define i1 @bools_logical_commute1_and1(i1 %b, i1 %c) {320; CHECK-LABEL: @bools_logical_commute1_and1(321; CHECK-NEXT: [[A:%.*]] = call i1 @gen1()322; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]]323; CHECK-NEXT: ret i1 [[OR]]324;325 %a = call i1 @gen1()326 %not = xor i1 %c, -1327 %and1 = and i1 %a, %not328 %and2 = select i1 %c, i1 %b, i1 false329 %or = select i1 %and1, i1 true, i1 %and2330 ret i1 %or331}332 333define i1 @bools_logical_commute1_and2(i1 %a, i1 %b, i1 %c) {334; CHECK-LABEL: @bools_logical_commute1_and2(335; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]336; CHECK-NEXT: ret i1 [[OR]]337;338 %not = xor i1 %c, -1339 %and1 = select i1 %a, i1 %not, i1 false340 %and2 = and i1 %c, %b341 %or = select i1 %and1, i1 true, i1 %and2342 ret i1 %or343}344 345define i1 @bools_logical_commute1_and1_and2(i1 %b, i1 %c) {346; CHECK-LABEL: @bools_logical_commute1_and1_and2(347; CHECK-NEXT: [[A:%.*]] = call i1 @gen1()348; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]]349; CHECK-NEXT: ret i1 [[OR]]350;351 %a = call i1 @gen1()352 %not = xor i1 %c, -1353 %and1 = and i1 %a, %not354 %and2 = and i1 %c, %b355 %or = select i1 %and1, i1 true, i1 %and2356 ret i1 %or357}358 359define <2 x i1> @bools_logical_commute2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {360; CHECK-LABEL: @bools_logical_commute2(361; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]362; CHECK-NEXT: ret <2 x i1> [[OR]]363;364 %not = xor <2 x i1> %c, <i1 -1, i1 -1>365 %and1 = select <2 x i1> %not, <2 x i1> %a, <2 x i1> <i1 false, i1 false>366 %and2 = select <2 x i1> %b, <2 x i1> %c, <2 x i1> <i1 false, i1 false>367 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2368 ret <2 x i1> %or369}370 371define <2 x i1> @bools_logical_commute2_and1(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {372; CHECK-LABEL: @bools_logical_commute2_and1(373; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]374; CHECK-NEXT: ret <2 x i1> [[OR]]375;376 %not = xor <2 x i1> %c, <i1 -1, i1 -1>377 %and1 = and <2 x i1> %not, %a378 %and2 = select <2 x i1> %b, <2 x i1> %c, <2 x i1> <i1 false, i1 false>379 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2380 ret <2 x i1> %or381}382 383define <2 x i1> @bools_logical_commute2_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {384; CHECK-LABEL: @bools_logical_commute2_and2(385; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]386; CHECK-NEXT: ret <2 x i1> [[OR]]387;388 %not = xor <2 x i1> %c, <i1 -1, i1 -1>389 %and1 = select <2 x i1> %not, <2 x i1> %a, <2 x i1> <i1 false, i1 false>390 %and2 = and <2 x i1> %b, %c391 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2392 ret <2 x i1> %or393}394 395define <2 x i1> @bools_logical_commute2_and1_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) {396; CHECK-LABEL: @bools_logical_commute2_and1_and2(397; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]]398; CHECK-NEXT: ret <2 x i1> [[OR]]399;400 %not = xor <2 x i1> %c, <i1 -1, i1 -1>401 %and1 = and <2 x i1> %not, %a402 %and2 = and <2 x i1> %b, %c403 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2404 ret <2 x i1> %or405}406 407define i1 @bools_logical_commute3(i1 %a, i1 %b, i1 %c) {408; CHECK-LABEL: @bools_logical_commute3(409; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[C:%.*]]410; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 [[B:%.*]], i1 [[A:%.*]]411; CHECK-NEXT: ret i1 [[OR]]412;413 %not = xor i1 %c, -1414 %and1 = select i1 %a, i1 %not, i1 false415 %and2 = select i1 %b, i1 %c, i1 false416 %or = select i1 %and1, i1 true, i1 %and2417 ret i1 %or418}419 420define i1 @bools_logical_commute3_and1(i1 %b, i1 %c) {421; CHECK-LABEL: @bools_logical_commute3_and1(422; CHECK-NEXT: [[A:%.*]] = call i1 @gen1()423; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]]424; CHECK-NEXT: ret i1 [[OR]]425;426 %a = call i1 @gen1()427 %not = xor i1 %c, -1428 %and1 = and i1 %a, %not429 %and2 = select i1 %b, i1 %c, i1 false430 %or = select i1 %and1, i1 true, i1 %and2431 ret i1 %or432}433 434define i1 @bools_logical_commute3_and2(i1 %a, i1 %b, i1 %c) {435; CHECK-LABEL: @bools_logical_commute3_and2(436; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]]437; CHECK-NEXT: ret i1 [[OR]]438;439 %not = xor i1 %c, -1440 %and1 = select i1 %a, i1 %not, i1 false441 %and2 = and i1 %b, %c442 %or = select i1 %and1, i1 true, i1 %and2443 ret i1 %or444}445 446define i1 @bools_logical_commute3_and1_and2(i1 %b, i1 %c) {447; CHECK-LABEL: @bools_logical_commute3_and1_and2(448; CHECK-NEXT: [[A:%.*]] = call i1 @gen1()449; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]]450; CHECK-NEXT: ret i1 [[OR]]451;452 %a = call i1 @gen1()453 %not = xor i1 %c, -1454 %and1 = and i1 %a, %not455 %and2 = and i1 %b, %c456 %or = select i1 %and1, i1 true, i1 %and2457 ret i1 %or458}459 460define i1 @bools2_logical_commute0(i1 %a, i1 %b, i1 %c) !prof !0 {461; CHECK-LABEL: @bools2_logical_commute0(462; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF1]]463; CHECK-NEXT: ret i1 [[OR]]464;465 %not = xor i1 %c, -1466 %and1 = select i1 %c, i1 %a, i1 false, !prof !1467 %and2 = select i1 %not, i1 %b, i1 false, !prof !2468 %or = select i1 %and1, i1 true, i1 %and2, !prof !3469 ret i1 %or470}471 472define i1 @bools2_logical_commute0_and1(i1 %a, i1 %b, i1 %c) !prof !0 {473; CHECK-LABEL: @bools2_logical_commute0_and1(474; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF2]]475; CHECK-NEXT: ret i1 [[OR]]476;477 %not = xor i1 %c, -1478 %and1 = and i1 %c, %a479 %and2 = select i1 %not, i1 %b, i1 false, !prof !1480 %or = select i1 %and1, i1 true, i1 %and2, !prof !2481 ret i1 %or482}483 484define i1 @bools2_logical_commute0_and2(i1 %a, i1 %b, i1 %c) {485; CHECK-LABEL: @bools2_logical_commute0_and2(486; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]487; CHECK-NEXT: ret i1 [[OR]]488;489 %not = xor i1 %c, -1490 %and1 = select i1 %c, i1 %a, i1 false491 %and2 = and i1 %not, %b492 %or = select i1 %and1, i1 true, i1 %and2493 ret i1 %or494}495 496define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) !prof !0 {497; CHECK-LABEL: @bools2_logical_commute0_and1_and2(498; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]], !prof [[PROF3]]499; CHECK-NEXT: ret i1 [[OR]]500;501 %not = xor i1 %c, -1502 %and1 = and i1 %c, %a503 %and2 = and i1 %not, %b504 %or = select i1 %and1, i1 true, i1 %and2, !prof !1505 ret i1 %or506}507 508define i1 @bools2_logical_commute1(i1 %a, i1 %b, i1 %c) {509; CHECK-LABEL: @bools2_logical_commute1(510; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]511; CHECK-NEXT: ret i1 [[OR]]512;513 %not = xor i1 %c, -1514 %and1 = select i1 %a, i1 %c, i1 false515 %and2 = select i1 %not, i1 %b, i1 false516 %or = select i1 %and1, i1 true, i1 %and2517 ret i1 %or518}519 520define i1 @bools2_logical_commute1_and1(i1 %a, i1 %b, i1 %c) {521; CHECK-LABEL: @bools2_logical_commute1_and1(522; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]523; CHECK-NEXT: ret i1 [[OR]]524;525 %not = xor i1 %c, -1526 %and1 = and i1 %a, %c527 %and2 = select i1 %not, i1 %b, i1 false528 %or = select i1 %and1, i1 true, i1 %and2529 ret i1 %or530}531 532define i1 @bools2_logical_commute1_and2(i1 %a, i1 %b, i1 %c) {533; CHECK-LABEL: @bools2_logical_commute1_and2(534; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]535; CHECK-NEXT: ret i1 [[OR]]536;537 %not = xor i1 %c, -1538 %and1 = select i1 %a, i1 %c, i1 false539 %and2 = and i1 %not, %b540 %or = select i1 %and1, i1 true, i1 %and2541 ret i1 %or542}543 544define i1 @bools2_logical_commute1_and1_and2(i1 %a, i1 %b, i1 %c) {545; CHECK-LABEL: @bools2_logical_commute1_and1_and2(546; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]547; CHECK-NEXT: ret i1 [[OR]]548;549 %not = xor i1 %c, -1550 %and1 = and i1 %a, %c551 %and2 = and i1 %not, %b552 %or = select i1 %and1, i1 true, i1 %and2553 ret i1 %or554}555 556define i1 @bools2_logical_commute2(i1 %a, i1 %b, i1 %c) {557; CHECK-LABEL: @bools2_logical_commute2(558; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]559; CHECK-NEXT: ret i1 [[OR]]560;561 %not = xor i1 %c, -1562 %and1 = select i1 %c, i1 %a, i1 false563 %and2 = select i1 %b, i1 %not, i1 false564 %or = select i1 %and1, i1 true, i1 %and2565 ret i1 %or566}567 568define i1 @bools2_logical_commute2_and1(i1 %a, i1 %b, i1 %c) {569; CHECK-LABEL: @bools2_logical_commute2_and1(570; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]571; CHECK-NEXT: ret i1 [[OR]]572;573 %not = xor i1 %c, -1574 %and1 = and i1 %c, %a575 %and2 = select i1 %b, i1 %not, i1 false576 %or = select i1 %and1, i1 true, i1 %and2577 ret i1 %or578}579 580define i1 @bools2_logical_commute2_and2(i1 %a, i1 %c) {581; CHECK-LABEL: @bools2_logical_commute2_and2(582; CHECK-NEXT: [[B:%.*]] = call i1 @gen1()583; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]]584; CHECK-NEXT: ret i1 [[OR]]585;586 %b = call i1 @gen1()587 %not = xor i1 %c, -1588 %and1 = select i1 %c, i1 %a, i1 false589 %and2 = and i1 %b, %not590 %or = select i1 %and1, i1 true, i1 %and2591 ret i1 %or592}593 594define i1 @bools2_logical_commute2_and1_and2(i1 %a, i1 %c) {595; CHECK-LABEL: @bools2_logical_commute2_and1_and2(596; CHECK-NEXT: [[B:%.*]] = call i1 @gen1()597; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]]598; CHECK-NEXT: ret i1 [[OR]]599;600 %b = call i1 @gen1()601 %not = xor i1 %c, -1602 %and1 = and i1 %c, %a603 %and2 = and i1 %b, %not604 %or = select i1 %and1, i1 true, i1 %and2605 ret i1 %or606}607 608; Freeze 'c' to prevent poison from leaking.609 610define i1 @bools2_logical_commute3(i1 %a, i1 %b, i1 %c) {611; CHECK-LABEL: @bools2_logical_commute3(612; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[C:%.*]]613; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 [[A:%.*]], i1 [[B:%.*]]614; CHECK-NEXT: ret i1 [[OR]]615;616 %not = xor i1 %c, -1617 %and1 = select i1 %a, i1 %c, i1 false618 %and2 = select i1 %b, i1 %not, i1 false619 %or = select i1 %and1, i1 true, i1 %and2620 ret i1 %or621}622 623; No freeze needed when 'c' is guaranteed not be poison.624; Intermediate logic folds may already reduce this.625 626define i1 @bools2_logical_commute3_nopoison(i1 %a, i1 %b, i1 noundef %c) {627; CHECK-LABEL: @bools2_logical_commute3_nopoison(628; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]629; CHECK-NEXT: ret i1 [[OR]]630;631 %not = xor i1 %c, -1632 %and1 = select i1 %a, i1 %c, i1 false633 %and2 = select i1 %b, i1 %not, i1 false634 %or = select i1 %and1, i1 true, i1 %and2635 ret i1 %or636}637 638define i1 @bools2_logical_commute3_and1(i1 %a, i1 %b, i1 %c) {639; CHECK-LABEL: @bools2_logical_commute3_and1(640; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]]641; CHECK-NEXT: ret i1 [[OR]]642;643 %not = xor i1 %c, -1644 %and1 = and i1 %a, %c645 %and2 = select i1 %b, i1 %not, i1 false646 %or = select i1 %and1, i1 true, i1 %and2647 ret i1 %or648}649 650define i1 @bools2_logical_commute3_and2(i1 %a, i1 %c) {651; CHECK-LABEL: @bools2_logical_commute3_and2(652; CHECK-NEXT: [[B:%.*]] = call i1 @gen1()653; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]]654; CHECK-NEXT: ret i1 [[OR]]655;656 %b = call i1 @gen1()657 %not = xor i1 %c, -1658 %and1 = select i1 %a, i1 %c, i1 false659 %and2 = and i1 %b, %not660 %or = select i1 %and1, i1 true, i1 %and2661 ret i1 %or662}663 664define i1 @bools2_logical_commute3_and1_and2(i1 %a, i1 %c) {665; CHECK-LABEL: @bools2_logical_commute3_and1_and2(666; CHECK-NEXT: [[B:%.*]] = call i1 @gen1()667; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]]668; CHECK-NEXT: ret i1 [[OR]]669;670 %b = call i1 @gen1()671 %not = xor i1 %c, -1672 %and1 = and i1 %a, %c673 %and2 = and i1 %b, %not674 %or = select i1 %and1, i1 true, i1 %and2675 ret i1 %or676}677 678define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i1 %y) {679; CHECK-LABEL: @orn_and_cmp_1_logical(680; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]681; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y:%.*]]682; CHECK-NEXT: ret i1 [[OR]]683;684 %x = icmp sgt i37 %a, %b685 %x_inv = icmp sle i37 %a, %b686 %and = select i1 %y, i1 %x, i1 false687 %or = select i1 %x_inv, i1 true, i1 %and688 ret i1 %or689}690 691; TODO: This should fold the same way as the next test.692 693define i1 @orn_and_cmp_1_partial_logical(i37 %a, i37 %b, i1 %y) {694; CHECK-LABEL: @orn_and_cmp_1_partial_logical(695; CHECK-NEXT: [[X:%.*]] = icmp sgt i37 [[A:%.*]], [[B:%.*]]696; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A]], [[B]]697; CHECK-NEXT: [[AND:%.*]] = and i1 [[X]], [[Y:%.*]]698; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[AND]]699; CHECK-NEXT: ret i1 [[OR]]700;701 %x = icmp sgt i37 %a, %b702 %x_inv = icmp sle i37 %a, %b703 %and = and i1 %x, %y704 %or = select i1 %x_inv, i1 true, i1 %and705 ret i1 %or706}707 708define i1 @orn_and_cmp_1_partial_logical_commute(i37 %a, i37 %b) {709; CHECK-LABEL: @orn_and_cmp_1_partial_logical_commute(710; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1()711; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]]712; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]]713; CHECK-NEXT: ret i1 [[OR]]714;715 %y = call i1 @gen1() ; thwart complexity-based canonicalization716 %x = icmp sgt i37 %a, %b717 %x_inv = icmp sle i37 %a, %b718 %and = and i1 %y, %x719 %or = select i1 %x_inv, i1 true, i1 %and720 ret i1 %or721}722 723; TODO: This does not require poison-safe (select) logical-or.724 725define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i1 %y) {726; CHECK-LABEL: @orn_and_cmp_2_logical(727; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]728; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X_INV]]729; CHECK-NEXT: ret i1 [[OR]]730;731 %x = icmp sge i16 %a, %b732 %x_inv = icmp slt i16 %a, %b733 %and = select i1 %y, i1 %x, i1 false734 %or = select i1 %and, i1 true, i1 %x_inv735 ret i1 %or736}737 738define i1 @orn_and_cmp_2_partial_logical(i16 %a, i16 %b, i1 %y) {739; CHECK-LABEL: @orn_and_cmp_2_partial_logical(740; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]741; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y:%.*]], [[X_INV]]742; CHECK-NEXT: ret i1 [[OR]]743;744 %x = icmp sge i16 %a, %b745 %x_inv = icmp slt i16 %a, %b746 %and = and i1 %x, %y747 %or = select i1 %and, i1 true, i1 %x_inv748 ret i1 %or749}750 751define i1 @orn_and_cmp_2_partial_logical_commute(i16 %a, i16 %b) {752; CHECK-LABEL: @orn_and_cmp_2_partial_logical_commute(753; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1()754; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]]755; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]]756; CHECK-NEXT: ret i1 [[OR]]757;758 %y = call i1 @gen1() ; thwart complexity-based canonicalization759 %x = icmp sge i16 %a, %b760 %x_inv = icmp slt i16 %a, %b761 %and = and i1 %y, %x762 %or = select i1 %and, i1 true, i1 %x_inv763 ret i1 %or764}765 766; PR58552 - this would crash trying to replace non-matching types767 768define <2 x i1> @not_logical_and(i1 %b, <2 x i32> %a) {769; CHECK-LABEL: @not_logical_and(770; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3)771; CHECK-NEXT: [[IMPLIED:%.*]] = icmp ugt <2 x i32> [[A]], splat (i32 1)772; CHECK-NEXT: [[AND:%.*]] = select i1 [[B:%.*]], <2 x i1> [[COND]], <2 x i1> zeroinitializer773; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[IMPLIED]], <2 x i1> splat (i1 true), <2 x i1> [[AND]]774; CHECK-NEXT: ret <2 x i1> [[OR]]775;776 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3>777 %implied = icmp ugt <2 x i32> %a, <i32 1, i32 1>778 %and = select i1 %b, <2 x i1> %cond, <2 x i1> zeroinitializer779 %or = select <2 x i1> %implied, <2 x i1> <i1 true, i1 true>, <2 x i1> %and780 ret <2 x i1> %or781}782 783; This could reduce, but we do not match select-of-vectors with scalar condition as logical-and.784 785define <2 x i1> @not_logical_and2(i1 %b, <2 x i32> %a) {786; CHECK-LABEL: @not_logical_and2(787; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3)788; CHECK-NEXT: [[IMPLIED:%.*]] = icmp ugt <2 x i32> [[A]], splat (i32 1)789; CHECK-NEXT: [[AND:%.*]] = select i1 [[B:%.*]], <2 x i1> [[COND]], <2 x i1> zeroinitializer790; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[AND]], <2 x i1> splat (i1 true), <2 x i1> [[IMPLIED]]791; CHECK-NEXT: ret <2 x i1> [[OR]]792;793 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3>794 %implied = icmp ugt <2 x i32> %a, <i32 1, i32 1>795 %and = select i1 %b, <2 x i1> %cond, <2 x i1> zeroinitializer796 %or = select <2 x i1> %and, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied797 ret <2 x i1> %or798}799 800!0 = !{!"function_entry_count", i64 1000}801!1 = !{!"branch_weights", i32 2, i32 3}802!2 = !{!"branch_weights", i32 5, i32 7}803!3 = !{!"branch_weights", i32 11, i32 13}804;.805; CHECK: [[META0:![0-9]+]] = !{!"function_entry_count", i64 1000}806; CHECK: [[PROF1]] = !{!"branch_weights", i32 2, i32 3}807; CHECK: [[PROF2]] = !{!"branch_weights", i32 3, i32 2}808; CHECK: [[PROF3]] = !{!"unknown", !"instcombine"}809;.810