1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instsimplify -S | FileCheck %s 3 4define i1 @logical_and_of_or_commute0(i1 %x, i1 %y) { 5; CHECK-LABEL: @logical_and_of_or_commute0( 6; CHECK-NEXT: ret i1 [[X:%.*]] 7; 8 %ynot = xor i1 %y, -1 9 %xory = select i1 %x, i1 true, i1 %y 10 %xorynot = select i1 %x, i1 true, i1 %ynot 11 %and = select i1 %xory, i1 %xorynot, i1 false 12 ret i1 %and 13} 14 15define <2 x i1> @logical_and_of_or_commute1(<2 x i1> %x, <2 x i1> %y) { 16; CHECK-LABEL: @logical_and_of_or_commute1( 17; CHECK-NEXT: ret <2 x i1> [[X:%.*]] 18; 19 %ynot = xor <2 x i1> %y, <i1 -1, i1 poison> 20 %xory = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 21 %xorynot = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %ynot 22 %and = select <2 x i1> %xory, <2 x i1> %xorynot, <2 x i1> zeroinitializer 23 ret <2 x i1> %and 24} 25 26define i1 @logical_and_of_or_commute2(i1 %x, i1 %y) { 27; CHECK-LABEL: @logical_and_of_or_commute2( 28; CHECK-NEXT: ret i1 [[X:%.*]] 29; 30 %ynot = xor i1 %y, -1 31 %xory = select i1 %x, i1 true, i1 %y 32 %xorynot = select i1 %ynot, i1 true, i1 %x 33 %and = select i1 %xory, i1 %xorynot, i1 false 34 ret i1 %and 35} 36 37define i1 @logical_and_of_or_commute3(i1 %x, i1 %y) { 38; CHECK-LABEL: @logical_and_of_or_commute3( 39; CHECK-NEXT: ret i1 [[X:%.*]] 40; 41 %ynot = xor i1 %y, -1 42 %xory = select i1 %y, i1 true, i1 %x 43 %xorynot = select i1 %ynot, i1 true, i1 %x 44 %and = select i1 %xory, i1 %xorynot, i1 false 45 ret i1 %and 46} 47 48define i1 @logical_and_of_or_commute4(i1 %x, i1 %y) { 49; CHECK-LABEL: @logical_and_of_or_commute4( 50; CHECK-NEXT: ret i1 [[X:%.*]] 51; 52 %ynot = xor i1 %y, -1 53 %xory = select i1 %x, i1 true, i1 %y 54 %xorynot = select i1 %x, i1 true, i1 %ynot 55 %and = select i1 %xorynot, i1 %xory, i1 false 56 ret i1 %and 57} 58 59define i1 @logical_and_of_or_commute5(i1 %x, i1 %y) { 60; CHECK-LABEL: @logical_and_of_or_commute5( 61; CHECK-NEXT: ret i1 [[X:%.*]] 62; 63 %ynot = xor i1 %y, -1 64 %xory = select i1 %y, i1 true, i1 %x 65 %xorynot = select i1 %x, i1 true, i1 %ynot 66 %and = select i1 %xorynot, i1 %xory, i1 false 67 ret i1 %and 68} 69 70define i1 @logical_and_of_or_commute6(i1 %x, i1 %y) { 71; CHECK-LABEL: @logical_and_of_or_commute6( 72; CHECK-NEXT: ret i1 [[X:%.*]] 73; 74 %ynot = xor i1 %y, -1 75 %xory = select i1 %x, i1 true, i1 %y 76 %xorynot = select i1 %ynot, i1 true, i1 %x 77 %and = select i1 %xorynot, i1 %xory, i1 false 78 ret i1 %and 79} 80 81define i1 @logical_and_of_or_commute7(i1 %x, i1 %y) { 82; CHECK-LABEL: @logical_and_of_or_commute7( 83; CHECK-NEXT: ret i1 [[X:%.*]] 84; 85 %ynot = xor i1 %y, -1 86 %xory = select i1 %y, i1 true, i1 %x 87 %xorynot = select i1 %ynot, i1 true, i1 %x 88 %and = select i1 %xorynot, i1 %xory, i1 false 89 ret i1 %and 90} 91 92; negative test - wrong logic op 93 94define i1 @logical_and_of_or_and(i1 %x, i1 %y) { 95; CHECK-LABEL: @logical_and_of_or_and( 96; CHECK-NEXT: [[XANDY:%.*]] = select i1 [[Y:%.*]], i1 [[X:%.*]], i1 false 97; CHECK-NEXT: [[YNOT:%.*]] = xor i1 [[Y]], true 98; CHECK-NEXT: [[XORYNOT:%.*]] = select i1 [[YNOT]], i1 true, i1 [[X]] 99; CHECK-NEXT: [[AND:%.*]] = select i1 [[XORYNOT]], i1 [[XANDY]], i1 false 100; CHECK-NEXT: ret i1 [[AND]] 101; 102 %xandy = select i1 %y, i1 %x, i1 false 103 %ynot = xor i1 %y, -1 104 %xorynot = select i1 %ynot, i1 true, i1 %x 105 %and = select i1 %xorynot, i1 %xandy, i1 false 106 ret i1 %and 107} 108 109; negative test - must have common operands 110 111define i1 @logical_and_of_or_no_common_op(i1 %x, i1 %y, i1 %z) { 112; CHECK-LABEL: @logical_and_of_or_no_common_op( 113; CHECK-NEXT: [[XORZ:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Z:%.*]] 114; CHECK-NEXT: [[YNOT:%.*]] = xor i1 [[Y:%.*]], true 115; CHECK-NEXT: [[XORYNOT:%.*]] = select i1 [[X]], i1 true, i1 [[YNOT]] 116; CHECK-NEXT: [[AND:%.*]] = select i1 [[XORYNOT]], i1 [[XORZ]], i1 false 117; CHECK-NEXT: ret i1 [[AND]] 118; 119 %xorz = select i1 %x, i1 true, i1 %z 120 %ynot = xor i1 %y, -1 121 %xorynot = select i1 %x, i1 true, i1 %ynot 122 %and = select i1 %xorynot, i1 %xorz, i1 false 123 ret i1 %and 124} 125 126; !(X | Y) && X --> false 127 128define i1 @or_not_and(i1 %x, i1 %y) { 129; CHECK-LABEL: @or_not_and( 130; CHECK-NEXT: ret i1 false 131; 132 %l.and = or i1 %x, %y 133 %not = xor i1 %l.and, true 134 %r = select i1 %not, i1 %x, i1 false 135 ret i1 %r 136} 137 138; vector case !(X | Y) && X --> false 139 140define <2 x i1> @or_not_and_vector(<2 x i1> %x, <2 x i1> %y) { 141; CHECK-LABEL: @or_not_and_vector( 142; CHECK-NEXT: ret <2 x i1> zeroinitializer 143; 144 %l.and = or <2 x i1> %x, %y 145 %not = xor <2 x i1> %l.and, <i1 true, i1 true> 146 %r = select <2 x i1> %not, <2 x i1> %x, <2 x i1> <i1 false, i1 false> 147 ret <2 x i1> %r 148} 149 150; vector case !(X | Y) && X --> false 151 152define <2 x i1> @or_not_and_vector_poison1(<2 x i1> %x, <2 x i1> %y) { 153; CHECK-LABEL: @or_not_and_vector_poison1( 154; CHECK-NEXT: ret <2 x i1> zeroinitializer 155; 156 %l.and = or <2 x i1> %x, %y 157 %not = xor <2 x i1> %l.and, <i1 poison, i1 true> 158 %r = select <2 x i1> %not, <2 x i1> %x, <2 x i1> <i1 false, i1 false> 159 ret <2 x i1> %r 160} 161 162; vector case !(X | Y) && X --> false 163 164define <2 x i1> @or_not_and_vector_poison2(<2 x i1> %x, <2 x i1> %y) { 165; CHECK-LABEL: @or_not_and_vector_poison2( 166; CHECK-NEXT: ret <2 x i1> zeroinitializer 167; 168 %l.and = or <2 x i1> %x, %y 169 %not = xor <2 x i1> %l.and, <i1 true, i1 true> 170 %r = select <2 x i1> %not, <2 x i1> %x, <2 x i1> <i1 poison, i1 false> 171 ret <2 x i1> %r 172} 173 174 175; !(X || Y) && X --> false 176 177define i1 @logical_or_not_and(i1 %x, i1 %y) { 178; CHECK-LABEL: @logical_or_not_and( 179; CHECK-NEXT: ret i1 false 180; 181 %l.and = select i1 %x, i1 true, i1 %y 182 %not = xor i1 %l.and, true 183 %r = select i1 %not, i1 %x, i1 false 184 ret i1 %r 185} 186 187; !(X || Y) && Y --> false 188 189define i1 @logical_or_not_and_commute_or(i1 %x, i1 %y) { 190; CHECK-LABEL: @logical_or_not_and_commute_or( 191; CHECK-NEXT: ret i1 false 192; 193 %l.and = select i1 %x, i1 true, i1 %y 194 %not = xor i1 %l.and, true 195 %r = select i1 %not, i1 %y, i1 false 196 ret i1 %r 197} 198 199; X && !(X || Y) --> false 200 201define i1 @logical_or_not_commute_and(i1 %x, i1 %y) { 202; CHECK-LABEL: @logical_or_not_commute_and( 203; CHECK-NEXT: ret i1 false 204; 205 %l.and = select i1 %x, i1 true, i1 %y 206 %not = xor i1 %l.and, true 207 %r = select i1 %x, i1 %not, i1 false 208 ret i1 %r 209} 210 211; Y && !(X || Y) --> false 212 213define i1 @logical_or_not_commute_and_commute_or(i1 %x, i1 %y) { 214; CHECK-LABEL: @logical_or_not_commute_and_commute_or( 215; CHECK-NEXT: ret i1 false 216; 217 %l.and = select i1 %x, i1 true, i1 %y 218 %not = xor i1 %l.and, true 219 %r = select i1 %y, i1 %not, i1 false 220 ret i1 %r 221} 222 223; vector case !(X || Y) && X --> false 224 225define <3 x i1> @logical_or_not_and_vector1(<3 x i1> %x, <3 x i1> %y) { 226; CHECK-LABEL: @logical_or_not_and_vector1( 227; CHECK-NEXT: ret <3 x i1> zeroinitializer 228; 229 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y 230 %not = xor <3 x i1> %l.and, <i1 true, i1 true, i1 true> 231 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false> 232 ret <3 x i1> %r 233} 234 235; TODO: this could transform to false 236; vector case !(X || Y) && X --> false 237 238define <3 x i1> @logical_or_not_and_vector1_poison1(<3 x i1> %x, <3 x i1> %y) { 239; CHECK-LABEL: @logical_or_not_and_vector1_poison1( 240; CHECK-NEXT: [[L_AND:%.*]] = select <3 x i1> [[X:%.*]], <3 x i1> <i1 true, i1 true, i1 poison>, <3 x i1> [[Y:%.*]] 241; CHECK-NEXT: [[NOT:%.*]] = xor <3 x i1> [[L_AND]], splat (i1 true) 242; CHECK-NEXT: [[R:%.*]] = select <3 x i1> [[NOT]], <3 x i1> [[X]], <3 x i1> zeroinitializer 243; CHECK-NEXT: ret <3 x i1> [[R]] 244; 245 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 poison>, <3 x i1> %y 246 %not = xor <3 x i1> %l.and, <i1 true, i1 true, i1 true> 247 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false> 248 ret <3 x i1> %r 249} 250 251; vector case !(X || Y) && X --> false 252 253define <3 x i1> @logical_or_not_and_vector1_poison2(<3 x i1> %x, <3 x i1> %y) { 254; CHECK-LABEL: @logical_or_not_and_vector1_poison2( 255; CHECK-NEXT: ret <3 x i1> zeroinitializer 256; 257 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y 258 %not = xor <3 x i1> %l.and, <i1 true, i1 poison, i1 true> 259 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 false, i1 false, i1 false> 260 ret <3 x i1> %r 261} 262 263; vector case !(X || Y) && X --> false 264 265define <3 x i1> @logical_or_not_and_vector1_poison3(<3 x i1> %x, <3 x i1> %y) { 266; CHECK-LABEL: @logical_or_not_and_vector1_poison3( 267; CHECK-NEXT: ret <3 x i1> zeroinitializer 268; 269 %l.and = select <3 x i1> %x, <3 x i1> <i1 true, i1 true, i1 true>, <3 x i1> %y 270 %not = xor <3 x i1> %l.and, <i1 true, i1 true, i1 true> 271 %r = select <3 x i1> %not, <3 x i1> %x, <3 x i1> <i1 poison, i1 false, i1 false> 272 ret <3 x i1> %r 273} 274 275; negative test - must have common operands 276 277define i1 @logical_not_or_and_negative1(i1 %x, i1 %y, i1 %z) { 278; CHECK-LABEL: @logical_not_or_and_negative1( 279; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 280; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 false, i1 [[Z:%.*]] 281; CHECK-NEXT: ret i1 [[R]] 282; 283 %or = or i1 %x, %y 284 %r = select i1 %or, i1 false, i1 %z 285 ret i1 %r 286} 287 288; !(x && y) || x --> true 289 290define i1 @logical_nand_logical_or_common_op_commute1(i1 %x, i1 %y) { 291; CHECK-LABEL: @logical_nand_logical_or_common_op_commute1( 292; CHECK-NEXT: ret i1 true 293; 294 %and = select i1 %x, i1 %y, i1 false 295 %nand = xor i1 %and, -1 296 %or = select i1 %nand, i1 true, i1 %x 297 ret i1 %or 298} 299 300define <2 x i1> @logical_nand_logical_or_common_op_commute2(<2 x i1> %x, <2 x i1> %y) { 301; CHECK-LABEL: @logical_nand_logical_or_common_op_commute2( 302; CHECK-NEXT: ret <2 x i1> splat (i1 true) 303; 304 %and = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer 305 %nand = xor <2 x i1> %and, <i1 -1, i1 -1> 306 %or = select <2 x i1> %nand, <2 x i1> <i1 -1, i1 -1>, <2 x i1> %x 307 ret <2 x i1> %or 308} 309 310define <2 x i1> @logical_nand_logical_or_common_op_commute3(<2 x i1> %x, <2 x i1> %y) { 311; CHECK-LABEL: @logical_nand_logical_or_common_op_commute3( 312; CHECK-NEXT: ret <2 x i1> splat (i1 true) 313; 314 %and = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer 315 %nand = xor <2 x i1> %and, <i1 -1, i1 poison> 316 %or = select <2 x i1> %x, <2 x i1> <i1 -1, i1 poison>, <2 x i1> %nand 317 ret <2 x i1> %or 318} 319 320define i1 @logical_nand_logical_or_common_op_commute4(i1 %x, i1 %y) { 321; CHECK-LABEL: @logical_nand_logical_or_common_op_commute4( 322; CHECK-NEXT: ret i1 true 323; 324 %and = select i1 %y, i1 %x, i1 false 325 %nand = xor i1 %and, -1 326 %or = select i1 %x, i1 true, i1 %nand 327 ret i1 %or 328} 329 330; TODO: This could fold the same as above (we don't match a partial poison vector as logical op). 331 332define <2 x i1> @logical_nand_logical_or_common_op_commute4_poison_vec(<2 x i1> %x, <2 x i1> %y) { 333; CHECK-LABEL: @logical_nand_logical_or_common_op_commute4_poison_vec( 334; CHECK-NEXT: [[AND:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> [[X:%.*]], <2 x i1> <i1 false, i1 poison> 335; CHECK-NEXT: [[NAND:%.*]] = xor <2 x i1> [[AND]], splat (i1 true) 336; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[X]], <2 x i1> splat (i1 true), <2 x i1> [[NAND]] 337; CHECK-NEXT: ret <2 x i1> [[OR]] 338; 339 %and = select <2 x i1> %y, <2 x i1> %x, <2 x i1> <i1 0, i1 poison> 340 %nand = xor <2 x i1> %and, <i1 -1, i1 -1> 341 %or = select <2 x i1> %x, <2 x i1> <i1 -1, i1 -1>, <2 x i1> %nand 342 ret <2 x i1> %or 343} 344 345; negative test - need common operand 346 347define i1 @logical_nand_logical_or(i1 %x, i1 %y, i1 %z) { 348; CHECK-LABEL: @logical_nand_logical_or( 349; CHECK-NEXT: [[AND:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false 350; CHECK-NEXT: [[NAND:%.*]] = xor i1 [[AND]], true 351; CHECK-NEXT: [[OR:%.*]] = select i1 [[NAND]], i1 true, i1 [[Z:%.*]] 352; CHECK-NEXT: ret i1 [[OR]] 353; 354 %and = select i1 %x, i1 %y, i1 false 355 %nand = xor i1 %and, -1 356 %or = select i1 %nand, i1 true, i1 %z 357 ret i1 %or 358} 359 360; (X | Y) ? false : X --> false 361 362define i1 @or_select_false_x_case1(i1 %x, i1 %y) { 363; CHECK-LABEL: @or_select_false_x_case1( 364; CHECK-NEXT: ret i1 false 365; 366 %or = or i1 %x, %y 367 %r = select i1 %or, i1 false, i1 %x 368 ret i1 %r 369} 370 371; (X | Y) ? false : X --> false 372 373define i1 @or_select_false_x_case2(i1 %x, i1 %y) { 374; CHECK-LABEL: @or_select_false_x_case2( 375; CHECK-NEXT: ret i1 false 376; 377 %or = or i1 %x, %y 378 %r = select i1 %or, i1 false, i1 %y 379 ret i1 %r 380} 381 382; vector case (X | Y) ? false : X --> false 383 384define <2 x i1> @or_select_false_x_vector(<2 x i1> %x, <2 x i1> %y) { 385; CHECK-LABEL: @or_select_false_x_vector( 386; CHECK-NEXT: ret <2 x i1> zeroinitializer 387; 388 %or = or <2 x i1> %x, %y 389 %r = select <2 x i1> %or, <2 x i1> <i1 false, i1 false>, <2 x i1> %x 390 ret <2 x i1> %r 391} 392 393; vector poison case (X | Y) ? false : X --> false 394 395define <2 x i1> @or_select_false_x_vector_poison(<2 x i1> %x, <2 x i1> %y) { 396; CHECK-LABEL: @or_select_false_x_vector_poison( 397; CHECK-NEXT: ret <2 x i1> zeroinitializer 398; 399 %or = or <2 x i1> %x, %y 400 %r = select <2 x i1> %or, <2 x i1> <i1 poison, i1 false>, <2 x i1> %x 401 ret <2 x i1> %r 402} 403 404; (X || Y) ? false : X --> false 405 406define i1 @logical_or_select_false_x_case1(i1 %x, i1 %y) { 407; CHECK-LABEL: @logical_or_select_false_x_case1( 408; CHECK-NEXT: ret i1 false 409; 410 %or = select i1 %x, i1 true, i1 %y 411 %r = select i1 %or, i1 false, i1 %x 412 ret i1 %r 413} 414 415; (X || Y) ? false : X --> false 416 417define i1 @logical_or_select_false_x_case2(i1 %x, i1 %y) { 418; CHECK-LABEL: @logical_or_select_false_x_case2( 419; CHECK-NEXT: ret i1 false 420; 421 %or = select i1 %y, i1 true, i1 %x 422 %r = select i1 %or, i1 false, i1 %x 423 ret i1 %r 424} 425 426; vector case (X || Y) ? false : X --> false 427 428define <2 x i1> @logical_or_select_false_x_vector(<2 x i1> %x, <2 x i1> %y) { 429; CHECK-LABEL: @logical_or_select_false_x_vector( 430; CHECK-NEXT: ret <2 x i1> zeroinitializer 431; 432 %or = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 433 %r = select <2 x i1> %or, <2 x i1> <i1 false, i1 false>, <2 x i1> %x 434 ret <2 x i1> %r 435} 436 437; TODO: this could transform to false 438; vector poison case (X || Y) ? false : X --> false 439 440define <2 x i1> @logical_or_select_false_x_vector_poison1(<2 x i1> %x, <2 x i1> %y) { 441; CHECK-LABEL: @logical_or_select_false_x_vector_poison1( 442; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]] 443; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[OR]], <2 x i1> zeroinitializer, <2 x i1> [[X]] 444; CHECK-NEXT: ret <2 x i1> [[R]] 445; 446 %or = select <2 x i1> %y, <2 x i1> <i1 poison, i1 true>, <2 x i1> %x 447 %r = select <2 x i1> %or, <2 x i1> <i1 false, i1 false>, <2 x i1> %x 448 ret <2 x i1> %r 449} 450 451; vector poison case (X || Y) ? false : X --> false 452 453define <2 x i1> @logical_or_select_false_x_vector_poison2(<2 x i1> %x, <2 x i1> %y) { 454; CHECK-LABEL: @logical_or_select_false_x_vector_poison2( 455; CHECK-NEXT: ret <2 x i1> zeroinitializer 456; 457 %or = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 458 %r = select <2 x i1> %or, <2 x i1> <i1 poison, i1 false>, <2 x i1> %x 459 ret <2 x i1> %r 460} 461 462; negative test - must have common operands 463 464define i1 @or_select_false_x_negative(i1 %x, i1 %y, i1 %z) { 465; CHECK-LABEL: @or_select_false_x_negative( 466; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 467; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 false, i1 [[Z:%.*]] 468; CHECK-NEXT: ret i1 [[R]] 469; 470 %or = or i1 %x, %y 471 %r = select i1 %or, i1 false, i1 %z 472 ret i1 %r 473} 474 475; (X || Y) ? X : Y --> X 476 477define i1 @select_or_same_op(i1 %x, i1 %y) { 478; CHECK-LABEL: @select_or_same_op( 479; CHECK-NEXT: ret i1 [[X:%.*]] 480; 481 %or = or i1 %x, %y 482 %r = select i1 %or, i1 %x, i1 %y 483 ret i1 %r 484} 485 486 487define i1 @select_or_same_op_commute(i1 %x, i1 %y) { 488; CHECK-LABEL: @select_or_same_op_commute( 489; CHECK-NEXT: ret i1 [[Y:%.*]] 490; 491 %or = or i1 %x, %y 492 %r = select i1 %or, i1 %y, i1 %x 493 ret i1 %r 494} 495 496 497define <2 x i1> @select_or_same_op_vector1(<2 x i1> %x, <2 x i1> %y) { 498; CHECK-LABEL: @select_or_same_op_vector1( 499; CHECK-NEXT: ret <2 x i1> [[X:%.*]] 500; 501 %or = or <2 x i1> %x, %y 502 %r = select <2 x i1> %or, <2 x i1> %x, <2 x i1> %y 503 ret <2 x i1> %r 504} 505 506 507define i1 @select_logic_or1_same_op(i1 %x, i1 %y) { 508; CHECK-LABEL: @select_logic_or1_same_op( 509; CHECK-NEXT: ret i1 [[X:%.*]] 510; 511 %or = select i1 %x, i1 true, i1 %y 512 %r = select i1 %or, i1 %x, i1 %y 513 ret i1 %r 514} 515 516 517define i1 @select_logic_or2_same_op(i1 %x, i1 %y) { 518; CHECK-LABEL: @select_logic_or2_same_op( 519; CHECK-NEXT: ret i1 [[X:%.*]] 520; 521 %or = select i1 %y, i1 true, i1 %x 522 %r = select i1 %or, i1 %x, i1 %y 523 ret i1 %r 524} 525 526 527define <2 x i1> @select_or_same_op_vector2(<2 x i1> %x, <2 x i1> %y) { 528; CHECK-LABEL: @select_or_same_op_vector2( 529; CHECK-NEXT: ret <2 x i1> [[X:%.*]] 530; 531 %or = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %y 532 %r = select <2 x i1> %or, <2 x i1> %x, <2 x i1> %y 533 ret <2 x i1> %r 534} 535 536; TODO: this could transform to X 537; (X || Y) ? X : Y --> X 538 539define <2 x i1> @select_or_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) { 540; CHECK-LABEL: @select_or_same_op_vector2_poison( 541; CHECK-NEXT: [[OR:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> <i1 true, i1 poison>, <2 x i1> [[Y:%.*]] 542; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[OR]], <2 x i1> [[X]], <2 x i1> [[Y]] 543; CHECK-NEXT: ret <2 x i1> [[R]] 544; 545 %or = select <2 x i1> %x, <2 x i1> <i1 true, i1 poison>, <2 x i1> %y 546 %r = select <2 x i1> %or, <2 x i1> %x, <2 x i1> %y 547 ret <2 x i1> %r 548} 549 550; negative test - must have common operands 551 552define i1 @select_or_same_op_negative(i1 %x, i1 %y, i1 %z) { 553; CHECK-LABEL: @select_or_same_op_negative( 554; CHECK-NEXT: [[OR:%.*]] = or i1 [[X:%.*]], [[Y:%.*]] 555; CHECK-NEXT: [[R:%.*]] = select i1 [[OR]], i1 [[X]], i1 [[Z:%.*]] 556; CHECK-NEXT: ret i1 [[R]] 557; 558 %or = or i1 %x, %y 559 %r = select i1 %or, i1 %x, i1 %z 560 ret i1 %r 561} 562 563; (X && Y) ? X : Y --> Y 564 565define i1 @select_and_same_op(i1 %x, i1 %y) { 566; CHECK-LABEL: @select_and_same_op( 567; CHECK-NEXT: ret i1 [[Y:%.*]] 568; 569 %a = and i1 %x, %y 570 %r = select i1 %a, i1 %x, i1 %y 571 ret i1 %r 572} 573 574 575define i1 @select_and_same_op_commute(i1 %x, i1 %y) { 576; CHECK-LABEL: @select_and_same_op_commute( 577; CHECK-NEXT: ret i1 [[X:%.*]] 578; 579 %a = and i1 %x, %y 580 %r = select i1 %a, i1 %y, i1 %x 581 ret i1 %r 582} 583 584 585define <2 x i1> @select_and_same_op_vector1(<2 x i1> %x, <2 x i1> %y) { 586; CHECK-LABEL: @select_and_same_op_vector1( 587; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 588; 589 %a = and <2 x i1> %x, %y 590 %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y 591 ret <2 x i1> %r 592} 593 594 595define i1 @select_logic_and1_same_op(i1 %x, i1 %y) { 596; CHECK-LABEL: @select_logic_and1_same_op( 597; CHECK-NEXT: ret i1 [[Y:%.*]] 598; 599 %a = select i1 %x, i1 %y, i1 false 600 %r = select i1 %a, i1 %x, i1 %y 601 ret i1 %r 602} 603 604 605define i1 @select_logic_and2_same_op(i1 %x, i1 %y) { 606; CHECK-LABEL: @select_logic_and2_same_op( 607; CHECK-NEXT: ret i1 [[Y:%.*]] 608; 609 %a = select i1 %y, i1 %x, i1 false 610 %r = select i1 %a, i1 %x, i1 %y 611 ret i1 %r 612} 613 614 615define <2 x i1> @select_and_same_op_vector2(<2 x i1> %x, <2 x i1> %y) { 616; CHECK-LABEL: @select_and_same_op_vector2( 617; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 618; 619 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer 620 %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y 621 ret <2 x i1> %r 622} 623 624; TODO: this could transform to Y 625; (X && Y) ? X : Y --> Y 626 627define <2 x i1> @select_and_same_op_vector2_poison(<2 x i1> %x, <2 x i1> %y) { 628; CHECK-LABEL: @select_and_same_op_vector2_poison( 629; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]], <2 x i1> <i1 false, i1 poison> 630; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[A]], <2 x i1> [[X]], <2 x i1> [[Y]] 631; CHECK-NEXT: ret <2 x i1> [[R]] 632; 633 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> <i1 false, i1 poison> 634 %r = select <2 x i1> %a, <2 x i1> %x, <2 x i1> %y 635 ret <2 x i1> %r 636} 637 638; negative test - must have common operands 639 640define i1 @select_and_same_op_negative(i1 %x, i1 %y, i1 %z) { 641; CHECK-LABEL: @select_and_same_op_negative( 642; CHECK-NEXT: [[A:%.*]] = and i1 [[X:%.*]], [[Y:%.*]] 643; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 [[X]], i1 [[Z:%.*]] 644; CHECK-NEXT: ret i1 [[R]] 645; 646 %a = and i1 %x, %y 647 %r = select i1 %a, i1 %x, i1 %z 648 ret i1 %r 649} 650 651define i1 @and_same_op(i1 %x) { 652; CHECK-LABEL: @and_same_op( 653; CHECK-NEXT: ret i1 [[X:%.*]] 654; 655 %r = select i1 %x, i1 %x, i1 false 656 ret i1 %r 657} 658 659define <2 x i1> @or_same_op(<2 x i1> %x) { 660; CHECK-LABEL: @or_same_op( 661; CHECK-NEXT: ret <2 x i1> [[X:%.*]] 662; 663 %r = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 664 ret <2 x i1> %r 665} 666 667define <2 x i1> @always_true_same_op(<2 x i1> %x) { 668; CHECK-LABEL: @always_true_same_op( 669; CHECK-NEXT: ret <2 x i1> splat (i1 true) 670; 671 %r = select <2 x i1> %x, <2 x i1> %x, <2 x i1> <i1 poison, i1 true> 672 ret <2 x i1> %r 673} 674 675define i1 @always_false_same_op(i1 %x) { 676; CHECK-LABEL: @always_false_same_op( 677; CHECK-NEXT: ret i1 false 678; 679 %r = select i1 %x, i1 false, i1 %x 680 ret i1 %r 681} 682 683; (X && Y) || Y --> Y 684 685define i1 @or_and_common_op_commute0(i1 %x, i1 %y) { 686; CHECK-LABEL: @or_and_common_op_commute0( 687; CHECK-NEXT: ret i1 [[Y:%.*]] 688; 689 %a = select i1 %x, i1 %y, i1 false 690 %r = select i1 %a, i1 true, i1 %y 691 ret i1 %r 692} 693 694define <2 x i1> @or_and_common_op_commute1(<2 x i1> %x, <2 x i1> %y) { 695; CHECK-LABEL: @or_and_common_op_commute1( 696; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 697; 698 %a = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer 699 %r = select <2 x i1> %a, <2 x i1> <i1 true, i1 true>, <2 x i1> %y 700 ret <2 x i1> %r 701} 702 703define <2 x i1> @or_and_common_op_commute2(<2 x i1> %x, <2 x i1> %y) { 704; CHECK-LABEL: @or_and_common_op_commute2( 705; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 706; 707 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> zeroinitializer 708 %r = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %a 709 ret <2 x i1> %r 710} 711 712; TODO: this could fold the same as above 713 714define <2 x i1> @or_and_common_op_commute2_poison(<2 x i1> %x, <2 x i1> %y) { 715; CHECK-LABEL: @or_and_common_op_commute2_poison( 716; CHECK-NEXT: [[A:%.*]] = select <2 x i1> [[X:%.*]], <2 x i1> [[Y:%.*]], <2 x i1> <i1 false, i1 poison> 717; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y]], <2 x i1> splat (i1 true), <2 x i1> [[A]] 718; CHECK-NEXT: ret <2 x i1> [[R]] 719; 720 %a = select <2 x i1> %x, <2 x i1> %y, <2 x i1> <i1 0, i1 poison> 721 %r = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %a 722 ret <2 x i1> %r 723} 724 725define <2 x i1> @or_and_common_op_commute3(<2 x i1> %x, <2 x i1> %y) { 726; CHECK-LABEL: @or_and_common_op_commute3( 727; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 728; 729 %a = select <2 x i1> %y, <2 x i1> %x, <2 x i1> zeroinitializer 730 %r = select <2 x i1> %y, <2 x i1> <i1 poison, i1 true>, <2 x i1> %a 731 ret <2 x i1> %r 732} 733 734; negative test 735 736define i1 @or_and_not_common_op(i1 %x, i1 %y, i1 %z) { 737; CHECK-LABEL: @or_and_not_common_op( 738; CHECK-NEXT: [[A:%.*]] = select i1 [[X:%.*]], i1 [[Y:%.*]], i1 false 739; CHECK-NEXT: [[R:%.*]] = select i1 [[A]], i1 true, i1 [[Z:%.*]] 740; CHECK-NEXT: ret i1 [[R]] 741; 742 %a = select i1 %x, i1 %y, i1 false 743 %r = select i1 %a, i1 true, i1 %z 744 ret i1 %r 745} 746 747; (X || Y) && Y --> Y 748 749define i1 @and_or_common_op_commute0(i1 %x, i1 %y) { 750; CHECK-LABEL: @and_or_common_op_commute0( 751; CHECK-NEXT: ret i1 [[Y:%.*]] 752; 753 %o = select i1 %x, i1 true, i1 %y 754 %r = select i1 %o, i1 %y, i1 false 755 ret i1 %r 756} 757 758define <2 x i1> @and_or_common_op_commute1(<2 x i1> %x, <2 x i1> %y) { 759; CHECK-LABEL: @and_or_common_op_commute1( 760; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 761; 762 %o = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 763 %r = select <2 x i1> %o, <2 x i1> %y, <2 x i1> zeroinitializer 764 ret <2 x i1> %r 765} 766 767 768define <2 x i1> @and_or_common_op_commute2(<2 x i1> %x, <2 x i1> %y) { 769; CHECK-LABEL: @and_or_common_op_commute2( 770; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 771; 772 %o = select <2 x i1> %x, <2 x i1> <i1 true, i1 true>, <2 x i1> %y 773 %r = select <2 x i1> %y, <2 x i1> %o, <2 x i1> <i1 0, i1 poison> 774 ret <2 x i1> %r 775} 776 777define <2 x i1> @and_or_common_op_commute3(<2 x i1> %x, <2 x i1> %y) { 778; CHECK-LABEL: @and_or_common_op_commute3( 779; CHECK-NEXT: ret <2 x i1> [[Y:%.*]] 780; 781 %o = select <2 x i1> %y, <2 x i1> <i1 true, i1 true>, <2 x i1> %x 782 %r = select <2 x i1> %y, <2 x i1> %o, <2 x i1> zeroinitializer 783 ret <2 x i1> %r 784} 785 786; TODO: this could fold the same as above 787 788define <2 x i1> @and_or_common_op_commute3_poison(<2 x i1> %x, <2 x i1> %y) { 789; CHECK-LABEL: @and_or_common_op_commute3_poison( 790; CHECK-NEXT: [[O:%.*]] = select <2 x i1> [[Y:%.*]], <2 x i1> <i1 poison, i1 true>, <2 x i1> [[X:%.*]] 791; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[Y]], <2 x i1> [[O]], <2 x i1> zeroinitializer 792; CHECK-NEXT: ret <2 x i1> [[R]] 793; 794 %o = select <2 x i1> %y, <2 x i1> <i1 poison, i1 true>, <2 x i1> %x 795 %r = select <2 x i1> %y, <2 x i1> %o, <2 x i1> zeroinitializer 796 ret <2 x i1> %r 797} 798 799; negative test 800 801define i1 @and_or_not_common_op(i1 %x, i1 %y, i1 %z) { 802; CHECK-LABEL: @and_or_not_common_op( 803; CHECK-NEXT: [[O:%.*]] = select i1 [[X:%.*]], i1 true, i1 [[Y:%.*]] 804; CHECK-NEXT: [[R:%.*]] = select i1 [[Z:%.*]], i1 [[O]], i1 false 805; CHECK-NEXT: ret i1 [[R]] 806; 807 %o = select i1 %x, i1 true, i1 %y 808 %r = select i1 %z, i1 %o, i1 false 809 ret i1 %r 810} 811