1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instsimplify -S | FileCheck %s 3 4define i64 @pow2(i32 %x) { 5; CHECK-LABEL: @pow2( 6; CHECK-NEXT: [[NEGX:%.*]] = sub i32 0, %x 7; CHECK-NEXT: [[X2:%.*]] = and i32 %x, [[NEGX]] 8; CHECK-NEXT: [[E:%.*]] = zext i32 [[X2]] to i64 9; CHECK-NEXT: ret i64 [[E]] 10; 11 %negx = sub i32 0, %x 12 %x2 = and i32 %x, %negx 13 %e = zext i32 %x2 to i64 14 %nege = sub i64 0, %e 15 %e2 = and i64 %e, %nege 16 ret i64 %e2 17} 18 19define i64 @pow2b(i32 %x) { 20; CHECK-LABEL: @pow2b( 21; CHECK-NEXT: [[SH:%.*]] = shl i32 2, %x 22; CHECK-NEXT: [[E:%.*]] = zext i32 [[SH]] to i64 23; CHECK-NEXT: ret i64 [[E]] 24; 25 %sh = shl i32 2, %x 26 %e = zext i32 %sh to i64 27 %nege = sub i64 0, %e 28 %e2 = and i64 %e, %nege 29 ret i64 %e2 30} 31 32define i1 @and_of_icmps0(i32 %b) { 33; CHECK-LABEL: @and_of_icmps0( 34; CHECK-NEXT: ret i1 false 35; 36 %1 = add i32 %b, 2 37 %2 = icmp ult i32 %1, 4 38 %cmp3 = icmp sgt i32 %b, 2 39 %cmp = and i1 %2, %cmp3 40 ret i1 %cmp 41} 42 43define <2 x i1> @and_of_icmps0_vec(<2 x i32> %b) { 44; CHECK-LABEL: @and_of_icmps0_vec( 45; CHECK-NEXT: ret <2 x i1> zeroinitializer 46; 47 %1 = add <2 x i32> %b, <i32 2, i32 2> 48 %2 = icmp ult <2 x i32> %1, <i32 4, i32 4> 49 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 50 %cmp = and <2 x i1> %2, %cmp3 51 ret <2 x i1> %cmp 52} 53 54define i1 @and_of_icmps1(i32 %b) { 55; CHECK-LABEL: @and_of_icmps1( 56; CHECK-NEXT: ret i1 false 57; 58 %1 = add nsw i32 %b, 2 59 %2 = icmp slt i32 %1, 4 60 %cmp3 = icmp sgt i32 %b, 2 61 %cmp = and i1 %2, %cmp3 62 ret i1 %cmp 63} 64 65define <2 x i1> @and_of_icmps1_vec(<2 x i32> %b) { 66; CHECK-LABEL: @and_of_icmps1_vec( 67; CHECK-NEXT: ret <2 x i1> zeroinitializer 68; 69 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 70 %2 = icmp slt <2 x i32> %1, <i32 4, i32 4> 71 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 72 %cmp = and <2 x i1> %2, %cmp3 73 ret <2 x i1> %cmp 74} 75 76define i1 @and_of_icmps2(i32 %b) { 77; CHECK-LABEL: @and_of_icmps2( 78; CHECK-NEXT: ret i1 false 79; 80 %1 = add i32 %b, 2 81 %2 = icmp ule i32 %1, 3 82 %cmp3 = icmp sgt i32 %b, 2 83 %cmp = and i1 %2, %cmp3 84 ret i1 %cmp 85} 86 87define <2 x i1> @and_of_icmps2_vec(<2 x i32> %b) { 88; CHECK-LABEL: @and_of_icmps2_vec( 89; CHECK-NEXT: ret <2 x i1> zeroinitializer 90; 91 %1 = add <2 x i32> %b, <i32 2, i32 2> 92 %2 = icmp ule <2 x i32> %1, <i32 3, i32 3> 93 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 94 %cmp = and <2 x i1> %2, %cmp3 95 ret <2 x i1> %cmp 96} 97 98define i1 @and_of_icmps3(i32 %b) { 99; CHECK-LABEL: @and_of_icmps3( 100; CHECK-NEXT: ret i1 false 101; 102 %1 = add nsw i32 %b, 2 103 %2 = icmp sle i32 %1, 3 104 %cmp3 = icmp sgt i32 %b, 2 105 %cmp = and i1 %2, %cmp3 106 ret i1 %cmp 107} 108 109define <2 x i1> @and_of_icmps3_vec(<2 x i32> %b) { 110; CHECK-LABEL: @and_of_icmps3_vec( 111; CHECK-NEXT: ret <2 x i1> zeroinitializer 112; 113 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 114 %2 = icmp sle <2 x i32> %1, <i32 3, i32 3> 115 %cmp3 = icmp sgt <2 x i32> %b, <i32 2, i32 2> 116 %cmp = and <2 x i1> %2, %cmp3 117 ret <2 x i1> %cmp 118} 119 120define i1 @and_of_icmps4(i32 %b) { 121; CHECK-LABEL: @and_of_icmps4( 122; CHECK-NEXT: ret i1 false 123; 124 %1 = add nuw i32 %b, 2 125 %2 = icmp ult i32 %1, 4 126 %cmp3 = icmp ugt i32 %b, 2 127 %cmp = and i1 %2, %cmp3 128 ret i1 %cmp 129} 130 131define <2 x i1> @and_of_icmps4_vec(<2 x i32> %b) { 132; CHECK-LABEL: @and_of_icmps4_vec( 133; CHECK-NEXT: ret <2 x i1> zeroinitializer 134; 135 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 136 %2 = icmp ult <2 x i32> %1, <i32 4, i32 4> 137 %cmp3 = icmp ugt <2 x i32> %b, <i32 2, i32 2> 138 %cmp = and <2 x i1> %2, %cmp3 139 ret <2 x i1> %cmp 140} 141 142define i1 @and_of_icmps5(i32 %b) { 143; CHECK-LABEL: @and_of_icmps5( 144; CHECK-NEXT: ret i1 false 145; 146 %1 = add nuw i32 %b, 2 147 %2 = icmp ule i32 %1, 3 148 %cmp3 = icmp ugt i32 %b, 2 149 %cmp = and i1 %2, %cmp3 150 ret i1 %cmp 151} 152 153define <2 x i1> @and_of_icmps5_vec(<2 x i32> %b) { 154; CHECK-LABEL: @and_of_icmps5_vec( 155; CHECK-NEXT: ret <2 x i1> zeroinitializer 156; 157 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 158 %2 = icmp ule <2 x i32> %1, <i32 3, i32 3> 159 %cmp3 = icmp ugt <2 x i32> %b, <i32 2, i32 2> 160 %cmp = and <2 x i1> %2, %cmp3 161 ret <2 x i1> %cmp 162} 163 164define i1 @or_of_icmps0(i32 %b) { 165; CHECK-LABEL: @or_of_icmps0( 166; CHECK-NEXT: ret i1 true 167; 168 %1 = add i32 %b, 2 169 %2 = icmp uge i32 %1, 4 170 %cmp3 = icmp sle i32 %b, 2 171 %cmp = or i1 %2, %cmp3 172 ret i1 %cmp 173} 174 175define <2 x i1> @or_of_icmps0_vec(<2 x i32> %b) { 176; CHECK-LABEL: @or_of_icmps0_vec( 177; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 178; 179 %1 = add <2 x i32> %b, <i32 2, i32 2> 180 %2 = icmp uge <2 x i32> %1, <i32 4, i32 4> 181 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 182 %cmp = or <2 x i1> %2, %cmp3 183 ret <2 x i1> %cmp 184} 185 186define i1 @or_of_icmps1(i32 %b) { 187; CHECK-LABEL: @or_of_icmps1( 188; CHECK-NEXT: ret i1 true 189; 190 %1 = add nsw i32 %b, 2 191 %2 = icmp sge i32 %1, 4 192 %cmp3 = icmp sle i32 %b, 2 193 %cmp = or i1 %2, %cmp3 194 ret i1 %cmp 195} 196 197define <2 x i1> @or_of_icmps1_vec(<2 x i32> %b) { 198; CHECK-LABEL: @or_of_icmps1_vec( 199; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 200; 201 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 202 %2 = icmp sge <2 x i32> %1, <i32 4, i32 4> 203 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 204 %cmp = or <2 x i1> %2, %cmp3 205 ret <2 x i1> %cmp 206} 207 208define i1 @or_of_icmps2(i32 %b) { 209; CHECK-LABEL: @or_of_icmps2( 210; CHECK-NEXT: ret i1 true 211; 212 %1 = add i32 %b, 2 213 %2 = icmp ugt i32 %1, 3 214 %cmp3 = icmp sle i32 %b, 2 215 %cmp = or i1 %2, %cmp3 216 ret i1 %cmp 217} 218 219define <2 x i1> @or_of_icmps2_vec(<2 x i32> %b) { 220; CHECK-LABEL: @or_of_icmps2_vec( 221; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 222; 223 %1 = add <2 x i32> %b, <i32 2, i32 2> 224 %2 = icmp ugt <2 x i32> %1, <i32 3, i32 3> 225 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 226 %cmp = or <2 x i1> %2, %cmp3 227 ret <2 x i1> %cmp 228} 229 230define i1 @or_of_icmps3(i32 %b) { 231; CHECK-LABEL: @or_of_icmps3( 232; CHECK-NEXT: ret i1 true 233; 234 %1 = add nsw i32 %b, 2 235 %2 = icmp sgt i32 %1, 3 236 %cmp3 = icmp sle i32 %b, 2 237 %cmp = or i1 %2, %cmp3 238 ret i1 %cmp 239} 240 241define <2 x i1> @or_of_icmps3_vec(<2 x i32> %b) { 242; CHECK-LABEL: @or_of_icmps3_vec( 243; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 244; 245 %1 = add nsw <2 x i32> %b, <i32 2, i32 2> 246 %2 = icmp sgt <2 x i32> %1, <i32 3, i32 3> 247 %cmp3 = icmp sle <2 x i32> %b, <i32 2, i32 2> 248 %cmp = or <2 x i1> %2, %cmp3 249 ret <2 x i1> %cmp 250} 251 252define i1 @or_of_icmps4(i32 %b) { 253; CHECK-LABEL: @or_of_icmps4( 254; CHECK-NEXT: ret i1 true 255; 256 %1 = add nuw i32 %b, 2 257 %2 = icmp uge i32 %1, 4 258 %cmp3 = icmp ule i32 %b, 2 259 %cmp = or i1 %2, %cmp3 260 ret i1 %cmp 261} 262 263define <2 x i1> @or_of_icmps4_vec(<2 x i32> %b) { 264; CHECK-LABEL: @or_of_icmps4_vec( 265; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 266; 267 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 268 %2 = icmp uge <2 x i32> %1, <i32 4, i32 4> 269 %cmp3 = icmp ule <2 x i32> %b, <i32 2, i32 2> 270 %cmp = or <2 x i1> %2, %cmp3 271 ret <2 x i1> %cmp 272} 273 274define i1 @or_of_icmps5(i32 %b) { 275; CHECK-LABEL: @or_of_icmps5( 276; CHECK-NEXT: ret i1 true 277; 278 %1 = add nuw i32 %b, 2 279 %2 = icmp ugt i32 %1, 3 280 %cmp3 = icmp ule i32 %b, 2 281 %cmp = or i1 %2, %cmp3 282 ret i1 %cmp 283} 284 285define <2 x i1> @or_of_icmps5_vec(<2 x i32> %b) { 286; CHECK-LABEL: @or_of_icmps5_vec( 287; CHECK-NEXT: ret <2 x i1> <i1 true, i1 true> 288; 289 %1 = add nuw <2 x i32> %b, <i32 2, i32 2> 290 %2 = icmp ugt <2 x i32> %1, <i32 3, i32 3> 291 %cmp3 = icmp ule <2 x i32> %b, <i32 2, i32 2> 292 %cmp = or <2 x i1> %2, %cmp3 293 ret <2 x i1> %cmp 294} 295 296define i32 @neg_nuw(i32 %x) { 297; CHECK-LABEL: @neg_nuw( 298; CHECK-NEXT: ret i32 0 299; 300 %neg = sub nuw i32 0, %x 301 ret i32 %neg 302} 303 304define i1 @and_icmp1(i32 %x, i32 %y) { 305; CHECK-LABEL: @and_icmp1( 306; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i32 %x, %y 307; CHECK-NEXT: ret i1 [[TMP1]] 308; 309 %1 = icmp ult i32 %x, %y 310 %2 = icmp ne i32 %y, 0 311 %3 = and i1 %1, %2 312 ret i1 %3 313} 314 315define i1 @and_icmp2(i32 %x, i32 %y) { 316; CHECK-LABEL: @and_icmp2( 317; CHECK-NEXT: ret i1 false 318; 319 %1 = icmp ult i32 %x, %y 320 %2 = icmp eq i32 %y, 0 321 %3 = and i1 %1, %2 322 ret i1 %3 323} 324 325define i1 @or_icmp1(i32 %x, i32 %y) { 326; CHECK-LABEL: @or_icmp1( 327; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 %y, 0 328; CHECK-NEXT: ret i1 [[TMP1]] 329; 330 %1 = icmp ult i32 %x, %y 331 %2 = icmp ne i32 %y, 0 332 %3 = or i1 %1, %2 333 ret i1 %3 334} 335 336define i1 @or_icmp2(i32 %x, i32 %y) { 337; CHECK-LABEL: @or_icmp2( 338; CHECK-NEXT: ret i1 true 339; 340 %1 = icmp uge i32 %x, %y 341 %2 = icmp ne i32 %y, 0 342 %3 = or i1 %1, %2 343 ret i1 %3 344} 345 346define i1 @or_icmp3(i32 %x, i32 %y) { 347; CHECK-LABEL: @or_icmp3( 348; CHECK-NEXT: [[TMP1:%.*]] = icmp uge i32 %x, %y 349; CHECK-NEXT: ret i1 [[TMP1]] 350; 351 %1 = icmp uge i32 %x, %y 352 %2 = icmp eq i32 %y, 0 353 %3 = or i1 %1, %2 354 ret i1 %3 355} 356 357define i1 @disjoint_cmps(i32 %A) { 358; CHECK-LABEL: @disjoint_cmps( 359; CHECK-NEXT: ret i1 false 360; 361 %B = icmp eq i32 %A, 1 362 %C = icmp sge i32 %A, 3 363 %D = and i1 %B, %C 364 ret i1 %D 365} 366 367define i1 @disjoint_cmps2(i32 %X) { 368; CHECK-LABEL: @disjoint_cmps2( 369; CHECK-NEXT: ret i1 false 370; 371 %a = icmp ult i32 %X, 31 372 %b = icmp slt i32 %X, 0 373 %c = and i1 %a, %b 374 ret i1 %c 375} 376 377; PR27869 - Look through casts to eliminate cmps and bitwise logic. 378 379define i32 @and_of_zexted_icmps(i32 %i) { 380; CHECK-LABEL: @and_of_zexted_icmps( 381; CHECK-NEXT: ret i32 0 382; 383 %cmp0 = icmp eq i32 %i, 0 384 %conv0 = zext i1 %cmp0 to i32 385 %cmp1 = icmp ugt i32 %i, 4 386 %conv1 = zext i1 %cmp1 to i32 387 %and = and i32 %conv0, %conv1 388 ret i32 %and 389} 390 391; Make sure vectors work too. 392 393define <4 x i32> @and_of_zexted_icmps_vec(<4 x i32> %i) { 394; CHECK-LABEL: @and_of_zexted_icmps_vec( 395; CHECK-NEXT: ret <4 x i32> zeroinitializer 396; 397 %cmp0 = icmp eq <4 x i32> %i, zeroinitializer 398 %conv0 = zext <4 x i1> %cmp0 to <4 x i32> 399 %cmp1 = icmp slt <4 x i32> %i, zeroinitializer 400 %conv1 = zext <4 x i1> %cmp1 to <4 x i32> 401 %and = and <4 x i32> %conv0, %conv1 402 ret <4 x i32> %and 403} 404 405; Try a different cast and weird types. 406 407define i5 @and_of_sexted_icmps(i3 %i) { 408; CHECK-LABEL: @and_of_sexted_icmps( 409; CHECK-NEXT: ret i5 0 410; 411 %cmp0 = icmp eq i3 %i, 0 412 %conv0 = sext i1 %cmp0 to i5 413 %cmp1 = icmp ugt i3 %i, 1 414 %conv1 = sext i1 %cmp1 to i5 415 %and = and i5 %conv0, %conv1 416 ret i5 %and 417} 418 419; Try a different cast and weird vector types. 420 421define i3 @and_of_bitcast_icmps_vec(<3 x i65> %i) { 422; CHECK-LABEL: @and_of_bitcast_icmps_vec( 423; CHECK-NEXT: ret i3 0 424; 425 %cmp0 = icmp sgt <3 x i65> %i, zeroinitializer 426 %conv0 = bitcast <3 x i1> %cmp0 to i3 427 %cmp1 = icmp slt <3 x i65> %i, zeroinitializer 428 %conv1 = bitcast <3 x i1> %cmp1 to i3 429 %and = and i3 %conv0, %conv1 430 ret i3 %and 431} 432 433; We can't do this if the casts are different. 434 435define i16 @and_of_different_cast_icmps(i8 %i) { 436; CHECK-LABEL: @and_of_different_cast_icmps( 437; CHECK-NEXT: [[CMP0:%.*]] = icmp eq i8 %i, 0 438; CHECK-NEXT: [[CONV0:%.*]] = zext i1 [[CMP0]] to i16 439; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i8 %i, 1 440; CHECK-NEXT: [[CONV1:%.*]] = sext i1 [[CMP1]] to i16 441; CHECK-NEXT: [[AND:%.*]] = and i16 [[CONV0]], [[CONV1]] 442; CHECK-NEXT: ret i16 [[AND]] 443; 444 %cmp0 = icmp eq i8 %i, 0 445 %conv0 = zext i1 %cmp0 to i16 446 %cmp1 = icmp eq i8 %i, 1 447 %conv1 = sext i1 %cmp1 to i16 448 %and = and i16 %conv0, %conv1 449 ret i16 %and 450} 451 452define <2 x i3> @and_of_different_cast_icmps_vec(<2 x i8> %i, <2 x i16> %j) { 453; CHECK-LABEL: @and_of_different_cast_icmps_vec( 454; CHECK-NEXT: [[CMP0:%.*]] = icmp eq <2 x i8> %i, zeroinitializer 455; CHECK-NEXT: [[CONV0:%.*]] = zext <2 x i1> [[CMP0]] to <2 x i3> 456; CHECK-NEXT: [[CMP1:%.*]] = icmp ugt <2 x i16> %j, <i16 1, i16 1> 457; CHECK-NEXT: [[CONV1:%.*]] = zext <2 x i1> [[CMP1]] to <2 x i3> 458; CHECK-NEXT: [[AND:%.*]] = and <2 x i3> [[CONV0]], [[CONV1]] 459; CHECK-NEXT: ret <2 x i3> [[AND]] 460; 461 %cmp0 = icmp eq <2 x i8> %i, zeroinitializer 462 %conv0 = zext <2 x i1> %cmp0 to <2 x i3> 463 %cmp1 = icmp ugt <2 x i16> %j, <i16 1, i16 1> 464 %conv1 = zext <2 x i1> %cmp1 to <2 x i3> 465 %and = and <2 x i3> %conv0, %conv1 466 ret <2 x i3> %and 467} 468 469