1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4declare i1 @gen1() 5 6define i1 @cond_eq_and(i8 %X, i8 %Y, i8 noundef %C) { 7; CHECK-LABEL: @cond_eq_and( 8; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], [[C:%.*]] 9; CHECK-NEXT: [[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]] 10; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 [[LHS]], i1 false 11; CHECK-NEXT: ret i1 [[RES]] 12; 13 %cond = icmp eq i8 %X, %C 14 %lhs = icmp ult i8 %X, %Y 15 %res = select i1 %cond, i1 %lhs, i1 false 16 ret i1 %res 17} 18 19define i1 @cond_eq_and_const(i8 %X, i8 %Y) { 20; CHECK-LABEL: @cond_eq_and_const( 21; CHECK-NEXT: [[COND:%.*]] = icmp eq i8 [[X:%.*]], 10 22; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 10 23; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 [[TMP1]], i1 false 24; CHECK-NEXT: ret i1 [[RES]] 25; 26 %cond = icmp eq i8 %X, 10 27 %lhs = icmp ult i8 %X, %Y 28 %res = select i1 %cond, i1 %lhs, i1 false 29 ret i1 %res 30} 31 32define i1 @cond_eq_or(i8 %X, i8 %Y, i8 noundef %C) { 33; CHECK-LABEL: @cond_eq_or( 34; CHECK-NEXT: [[COND:%.*]] = icmp ne i8 [[X:%.*]], [[C:%.*]] 35; CHECK-NEXT: [[LHS:%.*]] = icmp ult i8 [[X]], [[Y:%.*]] 36; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[LHS]] 37; CHECK-NEXT: ret i1 [[RES]] 38; 39 %cond = icmp ne i8 %X, %C 40 %lhs = icmp ult i8 %X, %Y 41 %res = select i1 %cond, i1 true, i1 %lhs 42 ret i1 %res 43} 44 45define i1 @cond_eq_or_const(i8 %X, i8 %Y) { 46; CHECK-LABEL: @cond_eq_or_const( 47; CHECK-NEXT: [[COND:%.*]] = icmp ne i8 [[X:%.*]], 10 48; CHECK-NEXT: [[TMP1:%.*]] = icmp ugt i8 [[Y:%.*]], 10 49; CHECK-NEXT: [[RES:%.*]] = select i1 [[COND]], i1 true, i1 [[TMP1]] 50; CHECK-NEXT: ret i1 [[RES]] 51; 52 %cond = icmp ne i8 %X, 10 53 %lhs = icmp ult i8 %X, %Y 54 %res = select i1 %cond, i1 true, i1 %lhs 55 ret i1 %res 56} 57 58define i1 @xor_and(i1 %c, i32 %X, i32 %Y) { 59; CHECK-LABEL: @xor_and( 60; CHECK-NEXT: [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 61; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 62; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C]], i1 true, i1 [[COMP]] 63; CHECK-NEXT: ret i1 [[SEL]] 64; 65 %comp = icmp ult i32 %X, %Y 66 %sel = select i1 %c, i1 %comp, i1 false 67 %res = xor i1 %sel, true 68 ret i1 %res 69} 70 71define <2 x i1> @xor_and2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { 72; CHECK-LABEL: @xor_and2( 73; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]] 74; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[COMP]], <2 x i1> <i1 false, i1 true> 75; CHECK-NEXT: ret <2 x i1> [[SEL]] 76; 77 %comp = icmp ult <2 x i32> %X, %Y 78 %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 true, i1 false> 79 %res = xor <2 x i1> %sel, <i1 true, i1 true> 80 ret <2 x i1> %res 81} 82 83@glb = global i8 0 84 85define <2 x i1> @xor_and3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { 86; CHECK-LABEL: @xor_and3( 87; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]] 88; 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> 89; CHECK-NEXT: ret <2 x i1> [[SEL]] 90; 91 %comp = icmp ult <2 x i32> %X, %Y 92 %sel = select <2 x i1> %c, <2 x i1> %comp, <2 x i1> <i1 ptrtoint (ptr @glb to i1), i1 false> 93 %res = xor <2 x i1> %sel, <i1 true, i1 true> 94 ret <2 x i1> %res 95} 96 97define i1 @xor_or(i1 %c, i32 %X, i32 %Y) { 98; CHECK-LABEL: @xor_or( 99; CHECK-NEXT: [[COMP:%.*]] = icmp uge i32 [[X:%.*]], [[Y:%.*]] 100; CHECK-NEXT: [[NOT_C:%.*]] = xor i1 [[C:%.*]], true 101; CHECK-NEXT: [[SEL:%.*]] = select i1 [[NOT_C]], i1 [[COMP]], i1 false 102; CHECK-NEXT: ret i1 [[SEL]] 103; 104 %comp = icmp ult i32 %X, %Y 105 %sel = select i1 %c, i1 true, i1 %comp 106 %res = xor i1 %sel, true 107 ret i1 %res 108} 109 110define <2 x i1> @xor_or2(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { 111; CHECK-LABEL: @xor_or2( 112; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]] 113; CHECK-NEXT: [[SEL:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> <i1 false, i1 true>, <2 x i1> [[COMP]] 114; CHECK-NEXT: ret <2 x i1> [[SEL]] 115; 116 %comp = icmp ult <2 x i32> %X, %Y 117 %sel = select <2 x i1> %c, <2 x i1> <i1 true, i1 false>, <2 x i1> %comp 118 %res = xor <2 x i1> %sel, <i1 true, i1 true> 119 ret <2 x i1> %res 120} 121 122define <2 x i1> @xor_or3(<2 x i1> %c, <2 x i32> %X, <2 x i32> %Y) { 123; CHECK-LABEL: @xor_or3( 124; CHECK-NEXT: [[COMP:%.*]] = icmp uge <2 x i32> [[X:%.*]], [[Y:%.*]] 125; 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]] 126; CHECK-NEXT: ret <2 x i1> [[SEL]] 127; 128 %comp = icmp ult <2 x i32> %X, %Y 129 %sel = select <2 x i1> %c, <2 x i1> <i1 ptrtoint (ptr @glb to i1), i1 false>, <2 x i1> %comp 130 %res = xor <2 x i1> %sel, <i1 true, i1 true> 131 ret <2 x i1> %res 132} 133 134define i1 @and_orn_cmp_1_logical(i32 %a, i32 %b, i1 %y) { 135; CHECK-LABEL: @and_orn_cmp_1_logical( 136; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 137; CHECK-NEXT: [[AND:%.*]] = select i1 [[X]], i1 [[Y:%.*]], i1 false 138; CHECK-NEXT: ret i1 [[AND]] 139; 140 %x = icmp sgt i32 %a, %b 141 %x_inv = icmp sle i32 %a, %b 142 %or = select i1 %y, i1 true, i1 %x_inv 143 %and = select i1 %x, i1 %or, i1 false 144 ret i1 %and 145} 146 147; TODO: This should fold the same way as the next test. 148 149define i1 @and_orn_cmp_1_partial_logical(i32 %a, i32 %b, i1 %y) { 150; CHECK-LABEL: @and_orn_cmp_1_partial_logical( 151; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 152; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i32 [[A]], [[B]] 153; CHECK-NEXT: [[OR:%.*]] = or i1 [[X_INV]], [[Y:%.*]] 154; CHECK-NEXT: [[AND:%.*]] = select i1 [[X]], i1 [[OR]], i1 false 155; CHECK-NEXT: ret i1 [[AND]] 156; 157 %x = icmp sgt i32 %a, %b 158 %x_inv = icmp sle i32 %a, %b 159 %or = or i1 %x_inv, %y 160 %and = select i1 %x, i1 %or, i1 false 161 ret i1 %and 162} 163 164define i1 @and_orn_cmp_1_partial_logical_commute(i32 %a, i32 %b) { 165; CHECK-LABEL: @and_orn_cmp_1_partial_logical_commute( 166; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1() 167; CHECK-NEXT: [[X:%.*]] = icmp sgt i32 [[A:%.*]], [[B:%.*]] 168; CHECK-NEXT: [[AND:%.*]] = select i1 [[X]], i1 [[Y]], i1 false 169; CHECK-NEXT: ret i1 [[AND]] 170; 171 %y = call i1 @gen1() ; thwart complexity-based canonicalization 172 %x = icmp sgt i32 %a, %b 173 %x_inv = icmp sle i32 %a, %b 174 %or = or i1 %y, %x_inv 175 %and = select i1 %x, i1 %or, i1 false 176 ret i1 %and 177} 178 179; TODO: This does not require poison-safe (select) logical-and. 180 181define i1 @andn_or_cmp_2_logical(i16 %a, i16 %b, i1 %y) { 182; CHECK-LABEL: @andn_or_cmp_2_logical( 183; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 184; CHECK-NEXT: [[AND:%.*]] = select i1 [[Y:%.*]], i1 [[X_INV]], i1 false 185; CHECK-NEXT: ret i1 [[AND]] 186; 187 %x = icmp sge i16 %a, %b 188 %x_inv = icmp slt i16 %a, %b 189 %or = select i1 %y, i1 true, i1 %x 190 %and = select i1 %or, i1 %x_inv, i1 false 191 ret i1 %and 192} 193 194define i1 @andn_or_cmp_2_partial_logical(i16 %a, i16 %b, i1 %y) { 195; CHECK-LABEL: @andn_or_cmp_2_partial_logical( 196; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 197; CHECK-NEXT: [[AND:%.*]] = and i1 [[Y:%.*]], [[X_INV]] 198; CHECK-NEXT: ret i1 [[AND]] 199; 200 %x = icmp sge i16 %a, %b 201 %x_inv = icmp slt i16 %a, %b 202 %or = or i1 %x, %y 203 %and = select i1 %or, i1 %x_inv, i1 false 204 ret i1 %and 205} 206 207define i1 @andn_or_cmp_2_partial_logical_commute(i16 %a, i16 %b) { 208; CHECK-LABEL: @andn_or_cmp_2_partial_logical_commute( 209; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1() 210; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 211; CHECK-NEXT: [[AND:%.*]] = and i1 [[Y]], [[X_INV]] 212; CHECK-NEXT: ret i1 [[AND]] 213; 214 %y = call i1 @gen1() ; thwart complexity-based canonicalization 215 %x = icmp sge i16 %a, %b 216 %x_inv = icmp slt i16 %a, %b 217 %or = or i1 %y, %x 218 %and = select i1 %or, i1 %x_inv, i1 false 219 ret i1 %and 220} 221 222; PR58552 - this would crash trying to replace non-matching types 223 224define <2 x i1> @not_logical_or(i1 %b, <2 x i32> %a) { 225; CHECK-LABEL: @not_logical_or( 226; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3) 227; CHECK-NEXT: [[IMPLIED:%.*]] = icmp slt <2 x i32> [[A]], splat (i32 -1) 228; CHECK-NEXT: [[OR:%.*]] = select i1 [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[IMPLIED]] 229; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[COND]], <2 x i1> [[OR]], <2 x i1> zeroinitializer 230; CHECK-NEXT: ret <2 x i1> [[AND]] 231; 232 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3> 233 %implied = icmp slt <2 x i32> %a, <i32 -1, i32 -1> 234 %or = select i1 %b, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied 235 %and = select <2 x i1> %cond, <2 x i1> %or, <2 x i1> zeroinitializer 236 ret <2 x i1> %and 237} 238 239; This could reduce, but we do not match select-of-vectors with scalar condition as logical-or. 240 241define <2 x i1> @not_logical_or2(i1 %b, <2 x i32> %a) { 242; CHECK-LABEL: @not_logical_or2( 243; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3) 244; CHECK-NEXT: [[IMPLIED:%.*]] = icmp slt <2 x i32> [[A]], splat (i32 -1) 245; CHECK-NEXT: [[OR:%.*]] = select i1 [[B:%.*]], <2 x i1> splat (i1 true), <2 x i1> [[IMPLIED]] 246; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[OR]], <2 x i1> [[COND]], <2 x i1> zeroinitializer 247; CHECK-NEXT: ret <2 x i1> [[AND]] 248; 249 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3> 250 %implied = icmp slt <2 x i32> %a, <i32 -1, i32 -1> 251 %or = select i1 %b, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied 252 %and = select <2 x i1> %or, <2 x i1> %cond, <2 x i1> zeroinitializer 253 ret <2 x i1> %and 254} 255 256define i1 @bools_logical_commute0(i1 %a, i1 %b, i1 %c) { 257; CHECK-LABEL: @bools_logical_commute0( 258; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 259; CHECK-NEXT: ret i1 [[OR]] 260; 261 %not = xor i1 %c, -1 262 %and1 = select i1 %not, i1 %a, i1 false 263 %and2 = select i1 %c, i1 %b, i1 false 264 %or = select i1 %and1, i1 true, i1 %and2 265 ret i1 %or 266} 267 268define i1 @bools_logical_commute0_and1(i1 %a, i1 %b, i1 %c) { 269; CHECK-LABEL: @bools_logical_commute0_and1( 270; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 271; CHECK-NEXT: ret i1 [[OR]] 272; 273 %not = xor i1 %c, -1 274 %and1 = and i1 %not, %a 275 %and2 = select i1 %c, i1 %b, i1 false 276 %or = select i1 %and1, i1 true, i1 %and2 277 ret i1 %or 278} 279 280define i1 @bools_logical_commute0_and2(i1 %a, i1 %b, i1 %c) { 281; CHECK-LABEL: @bools_logical_commute0_and2( 282; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 283; CHECK-NEXT: ret i1 [[OR]] 284; 285 %not = xor i1 %c, -1 286 %and1 = select i1 %not, i1 %a, i1 false 287 %and2 = and i1 %c, %b 288 %or = select i1 %and1, i1 true, i1 %and2 289 ret i1 %or 290} 291 292define i1 @bools_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) { 293; CHECK-LABEL: @bools_logical_commute0_and1_and2( 294; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 295; CHECK-NEXT: ret i1 [[OR]] 296; 297 %not = xor i1 %c, -1 298 %and1 = and i1 %not, %a 299 %and2 = and i1 %c, %b 300 %or = select i1 %and1, i1 true, i1 %and2 301 ret i1 %or 302} 303 304define i1 @bools_logical_commute1(i1 %a, i1 %b, i1 %c) { 305; CHECK-LABEL: @bools_logical_commute1( 306; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 307; CHECK-NEXT: ret i1 [[OR]] 308; 309 %not = xor i1 %c, -1 310 %and1 = select i1 %a, i1 %not, i1 false 311 %and2 = select i1 %c, i1 %b, i1 false 312 %or = select i1 %and1, i1 true, i1 %and2 313 ret i1 %or 314} 315 316define i1 @bools_logical_commute1_and1(i1 %b, i1 %c) { 317; CHECK-LABEL: @bools_logical_commute1_and1( 318; CHECK-NEXT: [[A:%.*]] = call i1 @gen1() 319; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]] 320; CHECK-NEXT: ret i1 [[OR]] 321; 322 %a = call i1 @gen1() 323 %not = xor i1 %c, -1 324 %and1 = and i1 %a, %not 325 %and2 = select i1 %c, i1 %b, i1 false 326 %or = select i1 %and1, i1 true, i1 %and2 327 ret i1 %or 328} 329 330define i1 @bools_logical_commute1_and2(i1 %a, i1 %b, i1 %c) { 331; CHECK-LABEL: @bools_logical_commute1_and2( 332; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 333; CHECK-NEXT: ret i1 [[OR]] 334; 335 %not = xor i1 %c, -1 336 %and1 = select i1 %a, i1 %not, i1 false 337 %and2 = and i1 %c, %b 338 %or = select i1 %and1, i1 true, i1 %and2 339 ret i1 %or 340} 341 342define i1 @bools_logical_commute1_and1_and2(i1 %b, i1 %c) { 343; CHECK-LABEL: @bools_logical_commute1_and1_and2( 344; CHECK-NEXT: [[A:%.*]] = call i1 @gen1() 345; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]] 346; CHECK-NEXT: ret i1 [[OR]] 347; 348 %a = call i1 @gen1() 349 %not = xor i1 %c, -1 350 %and1 = and i1 %a, %not 351 %and2 = and i1 %c, %b 352 %or = select i1 %and1, i1 true, i1 %and2 353 ret i1 %or 354} 355 356define <2 x i1> @bools_logical_commute2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) { 357; CHECK-LABEL: @bools_logical_commute2( 358; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]] 359; CHECK-NEXT: ret <2 x i1> [[OR]] 360; 361 %not = xor <2 x i1> %c, <i1 -1, i1 -1> 362 %and1 = select <2 x i1> %not, <2 x i1> %a, <2 x i1> <i1 false, i1 false> 363 %and2 = select <2 x i1> %b, <2 x i1> %c, <2 x i1> <i1 false, i1 false> 364 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2 365 ret <2 x i1> %or 366} 367 368define <2 x i1> @bools_logical_commute2_and1(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) { 369; CHECK-LABEL: @bools_logical_commute2_and1( 370; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]] 371; CHECK-NEXT: ret <2 x i1> [[OR]] 372; 373 %not = xor <2 x i1> %c, <i1 -1, i1 -1> 374 %and1 = and <2 x i1> %not, %a 375 %and2 = select <2 x i1> %b, <2 x i1> %c, <2 x i1> <i1 false, i1 false> 376 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2 377 ret <2 x i1> %or 378} 379 380define <2 x i1> @bools_logical_commute2_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) { 381; CHECK-LABEL: @bools_logical_commute2_and2( 382; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]] 383; CHECK-NEXT: ret <2 x i1> [[OR]] 384; 385 %not = xor <2 x i1> %c, <i1 -1, i1 -1> 386 %and1 = select <2 x i1> %not, <2 x i1> %a, <2 x i1> <i1 false, i1 false> 387 %and2 = and <2 x i1> %b, %c 388 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2 389 ret <2 x i1> %or 390} 391 392define <2 x i1> @bools_logical_commute2_and1_and2(<2 x i1> %a, <2 x i1> %b, <2 x i1> %c) { 393; CHECK-LABEL: @bools_logical_commute2_and1_and2( 394; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[C:%.*]], <2 x i1> [[B:%.*]], <2 x i1> [[A:%.*]] 395; CHECK-NEXT: ret <2 x i1> [[OR]] 396; 397 %not = xor <2 x i1> %c, <i1 -1, i1 -1> 398 %and1 = and <2 x i1> %not, %a 399 %and2 = and <2 x i1> %b, %c 400 %or = select <2 x i1> %and1, <2 x i1> <i1 true, i1 true>, <2 x i1> %and2 401 ret <2 x i1> %or 402} 403 404define i1 @bools_logical_commute3(i1 %a, i1 %b, i1 %c) { 405; CHECK-LABEL: @bools_logical_commute3( 406; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[C:%.*]] 407; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 [[B:%.*]], i1 [[A:%.*]] 408; CHECK-NEXT: ret i1 [[OR]] 409; 410 %not = xor i1 %c, -1 411 %and1 = select i1 %a, i1 %not, i1 false 412 %and2 = select i1 %b, i1 %c, i1 false 413 %or = select i1 %and1, i1 true, i1 %and2 414 ret i1 %or 415} 416 417define i1 @bools_logical_commute3_and1(i1 %b, i1 %c) { 418; CHECK-LABEL: @bools_logical_commute3_and1( 419; CHECK-NEXT: [[A:%.*]] = call i1 @gen1() 420; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]] 421; CHECK-NEXT: ret i1 [[OR]] 422; 423 %a = call i1 @gen1() 424 %not = xor i1 %c, -1 425 %and1 = and i1 %a, %not 426 %and2 = select i1 %b, i1 %c, i1 false 427 %or = select i1 %and1, i1 true, i1 %and2 428 ret i1 %or 429} 430 431define i1 @bools_logical_commute3_and2(i1 %a, i1 %b, i1 %c) { 432; CHECK-LABEL: @bools_logical_commute3_and2( 433; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A:%.*]] 434; CHECK-NEXT: ret i1 [[OR]] 435; 436 %not = xor i1 %c, -1 437 %and1 = select i1 %a, i1 %not, i1 false 438 %and2 = and i1 %b, %c 439 %or = select i1 %and1, i1 true, i1 %and2 440 ret i1 %or 441} 442 443define i1 @bools_logical_commute3_and1_and2(i1 %b, i1 %c) { 444; CHECK-LABEL: @bools_logical_commute3_and1_and2( 445; CHECK-NEXT: [[A:%.*]] = call i1 @gen1() 446; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[B:%.*]], i1 [[A]] 447; CHECK-NEXT: ret i1 [[OR]] 448; 449 %a = call i1 @gen1() 450 %not = xor i1 %c, -1 451 %and1 = and i1 %a, %not 452 %and2 = and i1 %b, %c 453 %or = select i1 %and1, i1 true, i1 %and2 454 ret i1 %or 455} 456 457define i1 @bools2_logical_commute0(i1 %a, i1 %b, i1 %c) { 458; CHECK-LABEL: @bools2_logical_commute0( 459; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 460; CHECK-NEXT: ret i1 [[OR]] 461; 462 %not = xor i1 %c, -1 463 %and1 = select i1 %c, i1 %a, i1 false 464 %and2 = select i1 %not, i1 %b, i1 false 465 %or = select i1 %and1, i1 true, i1 %and2 466 ret i1 %or 467} 468 469define i1 @bools2_logical_commute0_and1(i1 %a, i1 %b, i1 %c) { 470; CHECK-LABEL: @bools2_logical_commute0_and1( 471; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 472; CHECK-NEXT: ret i1 [[OR]] 473; 474 %not = xor i1 %c, -1 475 %and1 = and i1 %c, %a 476 %and2 = select i1 %not, i1 %b, i1 false 477 %or = select i1 %and1, i1 true, i1 %and2 478 ret i1 %or 479} 480 481define i1 @bools2_logical_commute0_and2(i1 %a, i1 %b, i1 %c) { 482; CHECK-LABEL: @bools2_logical_commute0_and2( 483; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 484; CHECK-NEXT: ret i1 [[OR]] 485; 486 %not = xor i1 %c, -1 487 %and1 = select i1 %c, i1 %a, i1 false 488 %and2 = and i1 %not, %b 489 %or = select i1 %and1, i1 true, i1 %and2 490 ret i1 %or 491} 492 493define i1 @bools2_logical_commute0_and1_and2(i1 %a, i1 %b, i1 %c) { 494; CHECK-LABEL: @bools2_logical_commute0_and1_and2( 495; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 496; CHECK-NEXT: ret i1 [[OR]] 497; 498 %not = xor i1 %c, -1 499 %and1 = and i1 %c, %a 500 %and2 = and i1 %not, %b 501 %or = select i1 %and1, i1 true, i1 %and2 502 ret i1 %or 503} 504 505define i1 @bools2_logical_commute1(i1 %a, i1 %b, i1 %c) { 506; CHECK-LABEL: @bools2_logical_commute1( 507; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 508; CHECK-NEXT: ret i1 [[OR]] 509; 510 %not = xor i1 %c, -1 511 %and1 = select i1 %a, i1 %c, i1 false 512 %and2 = select i1 %not, i1 %b, i1 false 513 %or = select i1 %and1, i1 true, i1 %and2 514 ret i1 %or 515} 516 517define i1 @bools2_logical_commute1_and1(i1 %a, i1 %b, i1 %c) { 518; CHECK-LABEL: @bools2_logical_commute1_and1( 519; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 520; CHECK-NEXT: ret i1 [[OR]] 521; 522 %not = xor i1 %c, -1 523 %and1 = and i1 %a, %c 524 %and2 = select i1 %not, i1 %b, i1 false 525 %or = select i1 %and1, i1 true, i1 %and2 526 ret i1 %or 527} 528 529define i1 @bools2_logical_commute1_and2(i1 %a, i1 %b, i1 %c) { 530; CHECK-LABEL: @bools2_logical_commute1_and2( 531; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 532; CHECK-NEXT: ret i1 [[OR]] 533; 534 %not = xor i1 %c, -1 535 %and1 = select i1 %a, i1 %c, i1 false 536 %and2 = and i1 %not, %b 537 %or = select i1 %and1, i1 true, i1 %and2 538 ret i1 %or 539} 540 541define i1 @bools2_logical_commute1_and1_and2(i1 %a, i1 %b, i1 %c) { 542; CHECK-LABEL: @bools2_logical_commute1_and1_and2( 543; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 544; CHECK-NEXT: ret i1 [[OR]] 545; 546 %not = xor i1 %c, -1 547 %and1 = and i1 %a, %c 548 %and2 = and i1 %not, %b 549 %or = select i1 %and1, i1 true, i1 %and2 550 ret i1 %or 551} 552 553define i1 @bools2_logical_commute2(i1 %a, i1 %b, i1 %c) { 554; CHECK-LABEL: @bools2_logical_commute2( 555; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 556; CHECK-NEXT: ret i1 [[OR]] 557; 558 %not = xor i1 %c, -1 559 %and1 = select i1 %c, i1 %a, i1 false 560 %and2 = select i1 %b, i1 %not, i1 false 561 %or = select i1 %and1, i1 true, i1 %and2 562 ret i1 %or 563} 564 565define i1 @bools2_logical_commute2_and1(i1 %a, i1 %b, i1 %c) { 566; CHECK-LABEL: @bools2_logical_commute2_and1( 567; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 568; CHECK-NEXT: ret i1 [[OR]] 569; 570 %not = xor i1 %c, -1 571 %and1 = and i1 %c, %a 572 %and2 = select i1 %b, i1 %not, i1 false 573 %or = select i1 %and1, i1 true, i1 %and2 574 ret i1 %or 575} 576 577define i1 @bools2_logical_commute2_and2(i1 %a, i1 %c) { 578; CHECK-LABEL: @bools2_logical_commute2_and2( 579; CHECK-NEXT: [[B:%.*]] = call i1 @gen1() 580; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]] 581; CHECK-NEXT: ret i1 [[OR]] 582; 583 %b = call i1 @gen1() 584 %not = xor i1 %c, -1 585 %and1 = select i1 %c, i1 %a, i1 false 586 %and2 = and i1 %b, %not 587 %or = select i1 %and1, i1 true, i1 %and2 588 ret i1 %or 589} 590 591define i1 @bools2_logical_commute2_and1_and2(i1 %a, i1 %c) { 592; CHECK-LABEL: @bools2_logical_commute2_and1_and2( 593; CHECK-NEXT: [[B:%.*]] = call i1 @gen1() 594; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]] 595; CHECK-NEXT: ret i1 [[OR]] 596; 597 %b = call i1 @gen1() 598 %not = xor i1 %c, -1 599 %and1 = and i1 %c, %a 600 %and2 = and i1 %b, %not 601 %or = select i1 %and1, i1 true, i1 %and2 602 ret i1 %or 603} 604 605; Freeze 'c' to prevent poison from leaking. 606 607define i1 @bools2_logical_commute3(i1 %a, i1 %b, i1 %c) { 608; CHECK-LABEL: @bools2_logical_commute3( 609; CHECK-NEXT: [[TMP1:%.*]] = freeze i1 [[C:%.*]] 610; CHECK-NEXT: [[OR:%.*]] = select i1 [[TMP1]], i1 [[A:%.*]], i1 [[B:%.*]] 611; CHECK-NEXT: ret i1 [[OR]] 612; 613 %not = xor i1 %c, -1 614 %and1 = select i1 %a, i1 %c, i1 false 615 %and2 = select i1 %b, i1 %not, i1 false 616 %or = select i1 %and1, i1 true, i1 %and2 617 ret i1 %or 618} 619 620; No freeze needed when 'c' is guaranteed not be poison. 621; Intermediate logic folds may already reduce this. 622 623define i1 @bools2_logical_commute3_nopoison(i1 %a, i1 %b, i1 noundef %c) { 624; CHECK-LABEL: @bools2_logical_commute3_nopoison( 625; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 626; CHECK-NEXT: ret i1 [[OR]] 627; 628 %not = xor i1 %c, -1 629 %and1 = select i1 %a, i1 %c, i1 false 630 %and2 = select i1 %b, i1 %not, i1 false 631 %or = select i1 %and1, i1 true, i1 %and2 632 ret i1 %or 633} 634 635define i1 @bools2_logical_commute3_and1(i1 %a, i1 %b, i1 %c) { 636; CHECK-LABEL: @bools2_logical_commute3_and1( 637; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B:%.*]] 638; CHECK-NEXT: ret i1 [[OR]] 639; 640 %not = xor i1 %c, -1 641 %and1 = and i1 %a, %c 642 %and2 = select i1 %b, i1 %not, i1 false 643 %or = select i1 %and1, i1 true, i1 %and2 644 ret i1 %or 645} 646 647define i1 @bools2_logical_commute3_and2(i1 %a, i1 %c) { 648; CHECK-LABEL: @bools2_logical_commute3_and2( 649; CHECK-NEXT: [[B:%.*]] = call i1 @gen1() 650; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]] 651; CHECK-NEXT: ret i1 [[OR]] 652; 653 %b = call i1 @gen1() 654 %not = xor i1 %c, -1 655 %and1 = select i1 %a, i1 %c, i1 false 656 %and2 = and i1 %b, %not 657 %or = select i1 %and1, i1 true, i1 %and2 658 ret i1 %or 659} 660 661define i1 @bools2_logical_commute3_and1_and2(i1 %a, i1 %c) { 662; CHECK-LABEL: @bools2_logical_commute3_and1_and2( 663; CHECK-NEXT: [[B:%.*]] = call i1 @gen1() 664; CHECK-NEXT: [[OR:%.*]] = select i1 [[C:%.*]], i1 [[A:%.*]], i1 [[B]] 665; CHECK-NEXT: ret i1 [[OR]] 666; 667 %b = call i1 @gen1() 668 %not = xor i1 %c, -1 669 %and1 = and i1 %a, %c 670 %and2 = and i1 %b, %not 671 %or = select i1 %and1, i1 true, i1 %and2 672 ret i1 %or 673} 674 675define i1 @orn_and_cmp_1_logical(i37 %a, i37 %b, i1 %y) { 676; CHECK-LABEL: @orn_and_cmp_1_logical( 677; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] 678; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y:%.*]] 679; CHECK-NEXT: ret i1 [[OR]] 680; 681 %x = icmp sgt i37 %a, %b 682 %x_inv = icmp sle i37 %a, %b 683 %and = select i1 %y, i1 %x, i1 false 684 %or = select i1 %x_inv, i1 true, i1 %and 685 ret i1 %or 686} 687 688; TODO: This should fold the same way as the next test. 689 690define i1 @orn_and_cmp_1_partial_logical(i37 %a, i37 %b, i1 %y) { 691; CHECK-LABEL: @orn_and_cmp_1_partial_logical( 692; CHECK-NEXT: [[X:%.*]] = icmp sgt i37 [[A:%.*]], [[B:%.*]] 693; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A]], [[B]] 694; CHECK-NEXT: [[AND:%.*]] = and i1 [[X]], [[Y:%.*]] 695; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[AND]] 696; CHECK-NEXT: ret i1 [[OR]] 697; 698 %x = icmp sgt i37 %a, %b 699 %x_inv = icmp sle i37 %a, %b 700 %and = and i1 %x, %y 701 %or = select i1 %x_inv, i1 true, i1 %and 702 ret i1 %or 703} 704 705define i1 @orn_and_cmp_1_partial_logical_commute(i37 %a, i37 %b) { 706; CHECK-LABEL: @orn_and_cmp_1_partial_logical_commute( 707; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1() 708; CHECK-NEXT: [[X_INV:%.*]] = icmp sle i37 [[A:%.*]], [[B:%.*]] 709; CHECK-NEXT: [[OR:%.*]] = select i1 [[X_INV]], i1 true, i1 [[Y]] 710; CHECK-NEXT: ret i1 [[OR]] 711; 712 %y = call i1 @gen1() ; thwart complexity-based canonicalization 713 %x = icmp sgt i37 %a, %b 714 %x_inv = icmp sle i37 %a, %b 715 %and = and i1 %y, %x 716 %or = select i1 %x_inv, i1 true, i1 %and 717 ret i1 %or 718} 719 720; TODO: This does not require poison-safe (select) logical-or. 721 722define i1 @orn_and_cmp_2_logical(i16 %a, i16 %b, i1 %y) { 723; CHECK-LABEL: @orn_and_cmp_2_logical( 724; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 725; CHECK-NEXT: [[OR:%.*]] = select i1 [[Y:%.*]], i1 true, i1 [[X_INV]] 726; CHECK-NEXT: ret i1 [[OR]] 727; 728 %x = icmp sge i16 %a, %b 729 %x_inv = icmp slt i16 %a, %b 730 %and = select i1 %y, i1 %x, i1 false 731 %or = select i1 %and, i1 true, i1 %x_inv 732 ret i1 %or 733} 734 735define i1 @orn_and_cmp_2_partial_logical(i16 %a, i16 %b, i1 %y) { 736; CHECK-LABEL: @orn_and_cmp_2_partial_logical( 737; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 738; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y:%.*]], [[X_INV]] 739; CHECK-NEXT: ret i1 [[OR]] 740; 741 %x = icmp sge i16 %a, %b 742 %x_inv = icmp slt i16 %a, %b 743 %and = and i1 %x, %y 744 %or = select i1 %and, i1 true, i1 %x_inv 745 ret i1 %or 746} 747 748define i1 @orn_and_cmp_2_partial_logical_commute(i16 %a, i16 %b) { 749; CHECK-LABEL: @orn_and_cmp_2_partial_logical_commute( 750; CHECK-NEXT: [[Y:%.*]] = call i1 @gen1() 751; CHECK-NEXT: [[X_INV:%.*]] = icmp slt i16 [[A:%.*]], [[B:%.*]] 752; CHECK-NEXT: [[OR:%.*]] = or i1 [[Y]], [[X_INV]] 753; CHECK-NEXT: ret i1 [[OR]] 754; 755 %y = call i1 @gen1() ; thwart complexity-based canonicalization 756 %x = icmp sge i16 %a, %b 757 %x_inv = icmp slt i16 %a, %b 758 %and = and i1 %y, %x 759 %or = select i1 %and, i1 true, i1 %x_inv 760 ret i1 %or 761} 762 763; PR58552 - this would crash trying to replace non-matching types 764 765define <2 x i1> @not_logical_and(i1 %b, <2 x i32> %a) { 766; CHECK-LABEL: @not_logical_and( 767; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3) 768; CHECK-NEXT: [[IMPLIED:%.*]] = icmp ugt <2 x i32> [[A]], splat (i32 1) 769; CHECK-NEXT: [[AND:%.*]] = select i1 [[B:%.*]], <2 x i1> [[COND]], <2 x i1> zeroinitializer 770; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[IMPLIED]], <2 x i1> splat (i1 true), <2 x i1> [[AND]] 771; CHECK-NEXT: ret <2 x i1> [[OR]] 772; 773 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3> 774 %implied = icmp ugt <2 x i32> %a, <i32 1, i32 1> 775 %and = select i1 %b, <2 x i1> %cond, <2 x i1> zeroinitializer 776 %or = select <2 x i1> %implied, <2 x i1> <i1 true, i1 true>, <2 x i1> %and 777 ret <2 x i1> %or 778} 779 780; This could reduce, but we do not match select-of-vectors with scalar condition as logical-and. 781 782define <2 x i1> @not_logical_and2(i1 %b, <2 x i32> %a) { 783; CHECK-LABEL: @not_logical_and2( 784; CHECK-NEXT: [[COND:%.*]] = icmp ult <2 x i32> [[A:%.*]], splat (i32 3) 785; CHECK-NEXT: [[IMPLIED:%.*]] = icmp ugt <2 x i32> [[A]], splat (i32 1) 786; CHECK-NEXT: [[AND:%.*]] = select i1 [[B:%.*]], <2 x i1> [[COND]], <2 x i1> zeroinitializer 787; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[AND]], <2 x i1> splat (i1 true), <2 x i1> [[IMPLIED]] 788; CHECK-NEXT: ret <2 x i1> [[OR]] 789; 790 %cond = icmp ult <2 x i32> %a, <i32 3, i32 3> 791 %implied = icmp ugt <2 x i32> %a, <i32 1, i32 1> 792 %and = select i1 %b, <2 x i1> %cond, <2 x i1> zeroinitializer 793 %or = select <2 x i1> %and, <2 x i1> <i1 true, i1 true>, <2 x i1> %implied 794 ret <2 x i1> %or 795} 796