1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -passes=instcombine -S | FileCheck %s 3 4; https://bugs.llvm.org/show_bug.cgi?id=6773 5 6; Patterns: 7; (x & m) | (y & ~m) 8; (x & m) ^ (y & ~m) 9; (x & m) + (y & ~m) 10; Should be transformed into: 11; (x & m) | (y & ~m) 12; And then into: 13; ((x ^ y) & m) ^ y 14 15; ============================================================================ ; 16; Most basic positive tests 17; ============================================================================ ; 18 19define i32 @p(i32 %x, i32 %y, i32 noundef %m) { 20; CHECK-LABEL: @p( 21; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] 22; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 23; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]] 24; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 25; CHECK-NEXT: ret i32 [[RET]] 26; 27 %and = and i32 %x, %m 28 %neg = xor i32 %m, -1 29 %and1 = and i32 %neg, %y 30 %ret = add i32 %and, %and1 31 ret i32 %ret 32} 33 34define <2 x i32> @p_splatvec(<2 x i32> %x, <2 x i32> %y, <2 x i32> noundef %m) { 35; CHECK-LABEL: @p_splatvec( 36; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], [[M:%.*]] 37; CHECK-NEXT: [[NEG:%.*]] = xor <2 x i32> [[M]], splat (i32 -1) 38; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], [[NEG]] 39; CHECK-NEXT: [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]] 40; CHECK-NEXT: ret <2 x i32> [[RET]] 41; 42 %and = and <2 x i32> %x, %m 43 %neg = xor <2 x i32> %m, <i32 -1, i32 -1> 44 %and1 = and <2 x i32> %neg, %y 45 %ret = add <2 x i32> %and, %and1 46 ret <2 x i32> %ret 47} 48 49define <3 x i32> @p_vec_undef(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) { 50; CHECK-LABEL: @p_vec_undef( 51; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]] 52; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 undef, i32 -1> 53; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[NEG]], [[Y:%.*]] 54; CHECK-NEXT: [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]] 55; CHECK-NEXT: ret <3 x i32> [[RET]] 56; 57 %and = and <3 x i32> %x, %m 58 %neg = xor <3 x i32> %m, <i32 -1, i32 undef, i32 -1> 59 %and1 = and <3 x i32> %neg, %y 60 %ret = add <3 x i32> %and, %and1 61 ret <3 x i32> %ret 62} 63 64define <3 x i32> @p_vec_poison(<3 x i32> %x, <3 x i32> %y, <3 x i32> noundef %m) { 65; CHECK-LABEL: @p_vec_poison( 66; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], [[M:%.*]] 67; CHECK-NEXT: [[NEG:%.*]] = xor <3 x i32> [[M]], <i32 -1, i32 poison, i32 -1> 68; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], [[NEG]] 69; CHECK-NEXT: [[RET:%.*]] = or disjoint <3 x i32> [[AND]], [[AND1]] 70; CHECK-NEXT: ret <3 x i32> [[RET]] 71; 72 %and = and <3 x i32> %x, %m 73 %neg = xor <3 x i32> %m, <i32 -1, i32 poison, i32 -1> 74 %and1 = and <3 x i32> %neg, %y 75 %ret = add <3 x i32> %and, %and1 76 ret <3 x i32> %ret 77} 78 79; ============================================================================ ; 80; Constant mask. 81; ============================================================================ ; 82 83define i32 @p_constmask(i32 %x, i32 %y) { 84; CHECK-LABEL: @p_constmask( 85; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280 86; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281 87; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 88; CHECK-NEXT: ret i32 [[RET]] 89; 90 %and = and i32 %x, 65280 91 %and1 = and i32 %y, -65281 92 %ret = add i32 %and, %and1 93 ret i32 %ret 94} 95 96define <2 x i32> @p_constmask_splatvec(<2 x i32> %x, <2 x i32> %y) { 97; CHECK-LABEL: @p_constmask_splatvec( 98; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 65280) 99; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], splat (i32 -65281) 100; CHECK-NEXT: [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]] 101; CHECK-NEXT: ret <2 x i32> [[RET]] 102; 103 %and = and <2 x i32> %x, <i32 65280, i32 65280> 104 %and1 = and <2 x i32> %y, <i32 -65281, i32 -65281> 105 %ret = add <2 x i32> %and, %and1 106 ret <2 x i32> %ret 107} 108 109define <2 x i32> @p_constmask_vec(<2 x i32> %x, <2 x i32> %y) { 110; CHECK-LABEL: @p_constmask_vec( 111; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 65280, i32 16776960> 112; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], <i32 -65281, i32 -16776961> 113; CHECK-NEXT: [[RET:%.*]] = add <2 x i32> [[AND]], [[AND1]] 114; CHECK-NEXT: ret <2 x i32> [[RET]] 115; 116 %and = and <2 x i32> %x, <i32 65280, i32 16776960> 117 %and1 = and <2 x i32> %y, <i32 -65281, i32 -16776961> 118 %ret = add <2 x i32> %and, %and1 119 ret <2 x i32> %ret 120} 121 122define <3 x i32> @p_constmask_vec_undef(<3 x i32> %x, <3 x i32> %y) { 123; CHECK-LABEL: @p_constmask_vec_undef( 124; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], <i32 65280, i32 undef, i32 65280> 125; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], <i32 -65281, i32 undef, i32 -65281> 126; CHECK-NEXT: [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]] 127; CHECK-NEXT: ret <3 x i32> [[RET]] 128; 129 %and = and <3 x i32> %x, <i32 65280, i32 undef, i32 65280> 130 %and1 = and <3 x i32> %y, <i32 -65281, i32 undef, i32 -65281> 131 %ret = add <3 x i32> %and, %and1 132 ret <3 x i32> %ret 133} 134 135; ============================================================================ ; 136; Constant mask with no common bits set, but common unset bits. 137; ============================================================================ ; 138 139define i32 @p_constmask2(i32 %x, i32 %y) { 140; CHECK-LABEL: @p_constmask2( 141; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 61440 142; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281 143; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 144; CHECK-NEXT: ret i32 [[RET]] 145; 146 %and = and i32 %x, 61440 147 %and1 = and i32 %y, -65281 148 %ret = add i32 %and, %and1 149 ret i32 %ret 150} 151 152define <2 x i32> @p_constmask2_splatvec(<2 x i32> %x, <2 x i32> %y) { 153; CHECK-LABEL: @p_constmask2_splatvec( 154; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], splat (i32 61440) 155; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], splat (i32 -65281) 156; CHECK-NEXT: [[RET:%.*]] = or disjoint <2 x i32> [[AND]], [[AND1]] 157; CHECK-NEXT: ret <2 x i32> [[RET]] 158; 159 %and = and <2 x i32> %x, <i32 61440, i32 61440> 160 %and1 = and <2 x i32> %y, <i32 -65281, i32 -65281> 161 %ret = add <2 x i32> %and, %and1 162 ret <2 x i32> %ret 163} 164 165define <2 x i32> @p_constmask2_vec(<2 x i32> %x, <2 x i32> %y) { 166; CHECK-LABEL: @p_constmask2_vec( 167; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[X:%.*]], <i32 61440, i32 16711680> 168; CHECK-NEXT: [[AND1:%.*]] = and <2 x i32> [[Y:%.*]], <i32 -65281, i32 -16776961> 169; CHECK-NEXT: [[RET:%.*]] = add <2 x i32> [[AND]], [[AND1]] 170; CHECK-NEXT: ret <2 x i32> [[RET]] 171; 172 %and = and <2 x i32> %x, <i32 61440, i32 16711680> 173 %and1 = and <2 x i32> %y, <i32 -65281, i32 -16776961> 174 %ret = add <2 x i32> %and, %and1 175 ret <2 x i32> %ret 176} 177 178define <3 x i32> @p_constmask2_vec_undef(<3 x i32> %x, <3 x i32> %y) { 179; CHECK-LABEL: @p_constmask2_vec_undef( 180; CHECK-NEXT: [[AND:%.*]] = and <3 x i32> [[X:%.*]], <i32 61440, i32 undef, i32 61440> 181; CHECK-NEXT: [[AND1:%.*]] = and <3 x i32> [[Y:%.*]], <i32 -65281, i32 undef, i32 -65281> 182; CHECK-NEXT: [[RET:%.*]] = add <3 x i32> [[AND]], [[AND1]] 183; CHECK-NEXT: ret <3 x i32> [[RET]] 184; 185 %and = and <3 x i32> %x, <i32 61440, i32 undef, i32 61440> 186 %and1 = and <3 x i32> %y, <i32 -65281, i32 undef, i32 -65281> 187 %ret = add <3 x i32> %and, %and1 188 ret <3 x i32> %ret 189} 190 191; ============================================================================ ; 192; Commutativity. 193; ============================================================================ ; 194 195; Used to make sure that the IR complexity sorting does not interfere. 196declare i32 @gen32() 197 198define i32 @p_commutative0(i32 %x, i32 %y, i32 noundef %m) { 199; CHECK-LABEL: @p_commutative0( 200; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] 201; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 202; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]] 203; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 204; CHECK-NEXT: ret i32 [[RET]] 205; 206 %and = and i32 %m, %x ; swapped order 207 %neg = xor i32 %m, -1 208 %and1 = and i32 %neg, %y 209 %ret = add i32 %and, %and1 210 ret i32 %ret 211} 212 213define i32 @p_commutative1(i32 %x, i32 noundef %m) { 214; CHECK-LABEL: @p_commutative1( 215; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32() 216; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] 217; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 218; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] 219; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 220; CHECK-NEXT: ret i32 [[RET]] 221; 222 %y = call i32 @gen32() 223 %and = and i32 %x, %m 224 %neg = xor i32 %m, -1 225 %and1 = and i32 %y, %neg; swapped order 226 %ret = add i32 %and, %and1 227 ret i32 %ret 228} 229 230define i32 @p_commutative2(i32 %x, i32 %y, i32 noundef %m) { 231; CHECK-LABEL: @p_commutative2( 232; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] 233; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 234; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]] 235; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]] 236; CHECK-NEXT: ret i32 [[RET]] 237; 238 %and = and i32 %x, %m 239 %neg = xor i32 %m, -1 240 %and1 = and i32 %neg, %y 241 %ret = add i32 %and1, %and ; swapped order 242 ret i32 %ret 243} 244 245define i32 @p_commutative3(i32 %x, i32 noundef %m) { 246; CHECK-LABEL: @p_commutative3( 247; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32() 248; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] 249; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 250; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] 251; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 252; CHECK-NEXT: ret i32 [[RET]] 253; 254 %y = call i32 @gen32() 255 %and = and i32 %m, %x ; swapped order 256 %neg = xor i32 %m, -1 257 %and1 = and i32 %y, %neg; swapped order 258 %ret = add i32 %and, %and1 259 ret i32 %ret 260} 261 262define i32 @p_commutative4(i32 %x, i32 %y, i32 noundef %m) { 263; CHECK-LABEL: @p_commutative4( 264; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] 265; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 266; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]] 267; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]] 268; CHECK-NEXT: ret i32 [[RET]] 269; 270 %and = and i32 %m, %x ; swapped order 271 %neg = xor i32 %m, -1 272 %and1 = and i32 %neg, %y 273 %ret = add i32 %and1, %and ; swapped order 274 ret i32 %ret 275} 276 277define i32 @p_commutative5(i32 %x, i32 noundef %m) { 278; CHECK-LABEL: @p_commutative5( 279; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32() 280; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] 281; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 282; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] 283; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]] 284; CHECK-NEXT: ret i32 [[RET]] 285; 286 %y = call i32 @gen32() 287 %and = and i32 %x, %m 288 %neg = xor i32 %m, -1 289 %and1 = and i32 %y, %neg; swapped order 290 %ret = add i32 %and1, %and ; swapped order 291 ret i32 %ret 292} 293 294define i32 @p_commutative6(i32 %x, i32 noundef %m) { 295; CHECK-LABEL: @p_commutative6( 296; CHECK-NEXT: [[Y:%.*]] = call i32 @gen32() 297; CHECK-NEXT: [[AND:%.*]] = and i32 [[M:%.*]], [[X:%.*]] 298; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 299; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y]], [[NEG]] 300; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]] 301; CHECK-NEXT: ret i32 [[RET]] 302; 303 %y = call i32 @gen32() 304 %and = and i32 %m, %x ; swapped order 305 %neg = xor i32 %m, -1 306 %and1 = and i32 %y, %neg; swapped order 307 %ret = add i32 %and1, %and ; swapped order 308 ret i32 %ret 309} 310 311define i32 @p_constmask_commutative(i32 %x, i32 %y) { 312; CHECK-LABEL: @p_constmask_commutative( 313; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280 314; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281 315; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND1]], [[AND]] 316; CHECK-NEXT: ret i32 [[RET]] 317; 318 %and = and i32 %x, 65280 319 %and1 = and i32 %y, -65281 320 %ret = add i32 %and1, %and ; swapped order 321 ret i32 %ret 322} 323 324; ============================================================================ ; 325; Negative tests. Should not be folded. 326; ============================================================================ ; 327 328; One use only. 329 330declare void @use32(i32) 331 332define i32 @n0_oneuse(i32 %x, i32 %y, i32 noundef %m) { 333; CHECK-LABEL: @n0_oneuse( 334; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] 335; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], -1 336; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]] 337; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 338; CHECK-NEXT: call void @use32(i32 [[AND]]) 339; CHECK-NEXT: call void @use32(i32 [[NEG]]) 340; CHECK-NEXT: call void @use32(i32 [[AND1]]) 341; CHECK-NEXT: ret i32 [[RET]] 342; 343 %and = and i32 %x, %m 344 %neg = xor i32 %m, -1 345 %and1 = and i32 %neg, %y 346 %ret = add i32 %and, %and1 347 call void @use32(i32 %and) 348 call void @use32(i32 %neg) 349 call void @use32(i32 %and1) 350 ret i32 %ret 351} 352 353define i32 @n0_constmask_oneuse(i32 %x, i32 %y) { 354; CHECK-LABEL: @n0_constmask_oneuse( 355; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280 356; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65281 357; CHECK-NEXT: [[RET:%.*]] = or disjoint i32 [[AND]], [[AND1]] 358; CHECK-NEXT: call void @use32(i32 [[AND]]) 359; CHECK-NEXT: call void @use32(i32 [[AND1]]) 360; CHECK-NEXT: ret i32 [[RET]] 361; 362 %and = and i32 %x, 65280 363 %and1 = and i32 %y, -65281 364 %ret = add i32 %and, %and1 365 call void @use32(i32 %and) 366 call void @use32(i32 %and1) 367 ret i32 %ret 368} 369 370; Bad xor constant 371 372define i32 @n1_badxor(i32 %x, i32 %y, i32 %m) { 373; CHECK-LABEL: @n1_badxor( 374; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], [[M:%.*]] 375; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M]], 1 376; CHECK-NEXT: [[AND1:%.*]] = and i32 [[NEG]], [[Y:%.*]] 377; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] 378; CHECK-NEXT: ret i32 [[RET]] 379; 380 %and = and i32 %x, %m 381 %neg = xor i32 %m, 1 ; not -1 382 %and1 = and i32 %neg, %y 383 %ret = add i32 %and, %and1 384 ret i32 %ret 385} 386 387; Different mask is used 388 389define i32 @n2_badmask(i32 %x, i32 %y, i32 %m1, i32 %m2) { 390; CHECK-LABEL: @n2_badmask( 391; CHECK-NEXT: [[AND:%.*]] = and i32 [[M1:%.*]], [[X:%.*]] 392; CHECK-NEXT: [[NEG:%.*]] = xor i32 [[M2:%.*]], -1 393; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], [[NEG]] 394; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] 395; CHECK-NEXT: ret i32 [[RET]] 396; 397 %and = and i32 %m1, %x 398 %neg = xor i32 %m2, -1 ; different mask, not %m1 399 %and1 = and i32 %neg, %y 400 %ret = add i32 %and, %and1 401 ret i32 %ret 402} 403 404; Different const mask is used 405 406define i32 @n3_constmask_badmask(i32 %x, i32 %y) { 407; CHECK-LABEL: @n3_constmask_badmask( 408; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280 409; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], -65280 410; CHECK-NEXT: [[RET:%.*]] = add i32 [[AND]], [[AND1]] 411; CHECK-NEXT: ret i32 [[RET]] 412; 413 %and = and i32 %x, 65280 414 %and1 = and i32 %y, -65280 ; not -65281, so they have one common bit set 415 %ret = add i32 %and, %and1 416 ret i32 %ret 417} 418 419define i32 @n3_constmask_samemask(i32 %x, i32 %y) { 420; CHECK-LABEL: @n3_constmask_samemask( 421; CHECK-NEXT: [[AND:%.*]] = and i32 [[X:%.*]], 65280 422; CHECK-NEXT: [[AND1:%.*]] = and i32 [[Y:%.*]], 65280 423; CHECK-NEXT: [[RET:%.*]] = add nuw nsw i32 [[AND]], [[AND1]] 424; CHECK-NEXT: ret i32 [[RET]] 425; 426 %and = and i32 %x, 65280 427 %and1 = and i32 %y, 65280 ; both masks are the same 428 %ret = add i32 %and, %and1 429 ret i32 %ret 430} 431