1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4;; ((X & 27) ? 27 : 0) 5 6define i41 @test5(i41 %X) { 7; CHECK-LABEL: @test5( 8; CHECK-NEXT: [[Y:%.*]] = and i41 [[X:%.*]], 32 9; CHECK-NEXT: ret i41 [[Y]] 10; 11 %Y = and i41 %X, 32 12 %t = icmp ne i41 %Y, 0 13 %V = select i1 %t, i41 32, i41 0 14 ret i41 %V 15} 16 17;; ((X & 27) ? 27 : 0) 18 19define i1023 @test6(i1023 %X) { 20; CHECK-LABEL: @test6( 21; CHECK-NEXT: [[Y:%.*]] = and i1023 [[X:%.*]], 64 22; CHECK-NEXT: ret i1023 [[Y]] 23; 24 %Y = and i1023 %X, 64 25 %t = icmp ne i1023 %Y, 0 26 %V = select i1 %t, i1023 64, i1023 0 27 ret i1023 %V 28} 29 30define i32 @test35(i32 %x) { 31; CHECK-LABEL: @test35( 32; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 33; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100 34; CHECK-NEXT: ret i32 [[COND]] 35; 36 %cmp = icmp sge i32 %x, 0 37 %cond = select i1 %cmp, i32 60, i32 100 38 ret i32 %cond 39} 40 41define <2 x i32> @test35vec(<2 x i32> %x) { 42; CHECK-LABEL: @test35vec( 43; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1> 44; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100> 45; CHECK-NEXT: ret <2 x i32> [[COND]] 46; 47 %cmp = icmp sge <2 x i32> %x, <i32 0, i32 0> 48 %cond = select <2 x i1> %cmp, <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100> 49 ret <2 x i32> %cond 50} 51 52; Make sure we can still perform this optimization with a truncate present 53define i32 @test35_with_trunc(i64 %x) { 54; CHECK-LABEL: @test35_with_trunc( 55; CHECK-NEXT: [[X1:%.*]] = trunc i64 [[X:%.*]] to i32 56; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X1]], -1 57; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100 58; CHECK-NEXT: ret i32 [[COND]] 59; 60 %x1 = trunc i64 %x to i32 61 %cmp = icmp sge i32 %x1, 0 62 %cond = select i1 %cmp, i32 60, i32 100 63 ret i32 %cond 64} 65 66define i32 @test36(i32 %x) { 67; CHECK-LABEL: @test36( 68; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[X:%.*]], 0 69; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 60, i32 100 70; CHECK-NEXT: ret i32 [[COND]] 71; 72 %cmp = icmp slt i32 %x, 0 73 %cond = select i1 %cmp, i32 60, i32 100 74 ret i32 %cond 75} 76 77define <2 x i32> @test36vec(<2 x i32> %x) { 78; CHECK-LABEL: @test36vec( 79; CHECK-NEXT: [[CMP:%.*]] = icmp slt <2 x i32> [[X:%.*]], zeroinitializer 80; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100> 81; CHECK-NEXT: ret <2 x i32> [[COND]] 82; 83 %cmp = icmp slt <2 x i32> %x, <i32 0, i32 0> 84 %cond = select <2 x i1> %cmp, <2 x i32> <i32 60, i32 60>, <2 x i32> <i32 100, i32 100> 85 ret <2 x i32> %cond 86} 87 88define i32 @test37(i32 %x) { 89; CHECK-LABEL: @test37( 90; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X:%.*]], -1 91; CHECK-NEXT: [[COND:%.*]] = select i1 [[CMP]], i32 1, i32 -1 92; CHECK-NEXT: ret i32 [[COND]] 93; 94 %cmp = icmp sgt i32 %x, -1 95 %cond = select i1 %cmp, i32 1, i32 -1 96 ret i32 %cond 97} 98 99define <2 x i32> @test37vec(<2 x i32> %x) { 100; CHECK-LABEL: @test37vec( 101; CHECK-NEXT: [[CMP:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1> 102; CHECK-NEXT: [[COND:%.*]] = select <2 x i1> [[CMP]], <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 -1, i32 -1> 103; CHECK-NEXT: ret <2 x i32> [[COND]] 104; 105 %cmp = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 106 %cond = select <2 x i1> %cmp, <2 x i32> <i32 1, i32 1>, <2 x i32> <i32 -1, i32 -1> 107 ret <2 x i32> %cond 108} 109 110define i32 @test65(i64 %x) { 111; CHECK-LABEL: @test65( 112; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 16 113; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0 114; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 42, i32 40 115; CHECK-NEXT: ret i32 [[TMP3]] 116; 117 %1 = and i64 %x, 16 118 %2 = icmp ne i64 %1, 0 119 %3 = select i1 %2, i32 40, i32 42 120 ret i32 %3 121} 122 123define <2 x i32> @test65vec(<2 x i64> %x) { 124; CHECK-LABEL: @test65vec( 125; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], <i64 16, i64 16> 126; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer 127; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 42, i32 42>, <2 x i32> <i32 40, i32 40> 128; CHECK-NEXT: ret <2 x i32> [[TMP3]] 129; 130 %1 = and <2 x i64> %x, <i64 16, i64 16> 131 %2 = icmp ne <2 x i64> %1, zeroinitializer 132 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 133 ret <2 x i32> %3 134} 135 136define i32 @test66(i64 %x) { 137; CHECK-LABEL: @test66( 138; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 4294967296 139; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0 140; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 42, i32 40 141; CHECK-NEXT: ret i32 [[TMP3]] 142; 143 %1 = and i64 %x, 4294967296 144 %2 = icmp ne i64 %1, 0 145 %3 = select i1 %2, i32 40, i32 42 146 ret i32 %3 147} 148 149define <2 x i32> @test66vec(<2 x i64> %x) { 150; CHECK-LABEL: @test66vec( 151; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i64> [[X:%.*]], <i64 4294967296, i64 4294967296> 152; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i64> [[TMP1]], zeroinitializer 153; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 42, i32 42>, <2 x i32> <i32 40, i32 40> 154; CHECK-NEXT: ret <2 x i32> [[TMP3]] 155; 156 %1 = and <2 x i64> %x, <i64 4294967296, i64 4294967296> 157 %2 = icmp ne <2 x i64> %1, zeroinitializer 158 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 159 ret <2 x i32> %3 160} 161 162; Make sure we don't try to optimize a scalar 'and' with a vector select. 163define <2 x i32> @test66vec_scalar_and(i64 %x) { 164; CHECK-LABEL: @test66vec_scalar_and( 165; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[X:%.*]], 4294967296 166; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i64 [[TMP1]], 0 167; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], <2 x i32> <i32 42, i32 42>, <2 x i32> <i32 40, i32 40> 168; CHECK-NEXT: ret <2 x i32> [[TMP3]] 169; 170 %1 = and i64 %x, 4294967296 171 %2 = icmp ne i64 %1, 0 172 %3 = select i1 %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 173 ret <2 x i32> %3 174} 175 176define i32 @test67(i16 %x) { 177; CHECK-LABEL: @test67( 178; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], 4 179; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0 180; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 42, i32 40 181; CHECK-NEXT: ret i32 [[TMP3]] 182; 183 %1 = and i16 %x, 4 184 %2 = icmp ne i16 %1, 0 185 %3 = select i1 %2, i32 40, i32 42 186 ret i32 %3 187} 188 189define <2 x i32> @test67vec(<2 x i16> %x) { 190; CHECK-LABEL: @test67vec( 191; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i16> [[X:%.*]], <i16 4, i16 4> 192; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i16> [[TMP1]], zeroinitializer 193; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 42, i32 42>, <2 x i32> <i32 40, i32 40> 194; CHECK-NEXT: ret <2 x i32> [[TMP3]] 195; 196 %1 = and <2 x i16> %x, <i16 4, i16 4> 197 %2 = icmp ne <2 x i16> %1, zeroinitializer 198 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 199 ret <2 x i32> %3 200} 201 202define i32 @test71(i32 %x) { 203; CHECK-LABEL: @test71( 204; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128 205; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 206; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 42, i32 40 207; CHECK-NEXT: ret i32 [[TMP3]] 208; 209 %1 = and i32 %x, 128 210 %2 = icmp ne i32 %1, 0 211 %3 = select i1 %2, i32 40, i32 42 212 ret i32 %3 213} 214 215define <2 x i32> @test71vec(<2 x i32> %x) { 216; CHECK-LABEL: @test71vec( 217; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 128, i32 128> 218; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer 219; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 42, i32 42>, <2 x i32> <i32 40, i32 40> 220; CHECK-NEXT: ret <2 x i32> [[TMP3]] 221; 222 %1 = and <2 x i32> %x, <i32 128, i32 128> 223 %2 = icmp ne <2 x i32> %1, <i32 0, i32 0> 224 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 225 ret <2 x i32> %3 226} 227 228define i32 @test72(i32 %x) { 229; CHECK-LABEL: @test72( 230; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[X:%.*]], 128 231; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[TMP1]], 0 232; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42 233; CHECK-NEXT: ret i32 [[TMP3]] 234; 235 %1 = and i32 %x, 128 236 %2 = icmp eq i32 %1, 0 237 %3 = select i1 %2, i32 40, i32 42 238 ret i32 %3 239} 240 241define <2 x i32> @test72vec(<2 x i32> %x) { 242; CHECK-LABEL: @test72vec( 243; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[X:%.*]], <i32 128, i32 128> 244; CHECK-NEXT: [[TMP2:%.*]] = icmp eq <2 x i32> [[TMP1]], zeroinitializer 245; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 246; CHECK-NEXT: ret <2 x i32> [[TMP3]] 247; 248 %1 = and <2 x i32> %x, <i32 128, i32 128> 249 %2 = icmp eq <2 x i32> %1, <i32 0, i32 0> 250 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 251 ret <2 x i32> %3 252} 253 254define i32 @test73(i32 %x) { 255; CHECK-LABEL: @test73( 256; CHECK-NEXT: [[TMP1:%.*]] = trunc i32 [[X:%.*]] to i8 257; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], -1 258; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 40, i32 42 259; CHECK-NEXT: ret i32 [[TMP3]] 260; 261 %1 = trunc i32 %x to i8 262 %2 = icmp sgt i8 %1, -1 263 %3 = select i1 %2, i32 40, i32 42 264 ret i32 %3 265} 266 267define <2 x i32> @test73vec(<2 x i32> %x) { 268; CHECK-LABEL: @test73vec( 269; CHECK-NEXT: [[TMP1:%.*]] = trunc <2 x i32> [[X:%.*]] to <2 x i8> 270; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt <2 x i8> [[TMP1]], <i8 -1, i8 -1> 271; CHECK-NEXT: [[TMP3:%.*]] = select <2 x i1> [[TMP2]], <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 272; CHECK-NEXT: ret <2 x i32> [[TMP3]] 273; 274 %1 = trunc <2 x i32> %x to <2 x i8> 275 %2 = icmp sgt <2 x i8> %1, <i8 -1, i8 -1> 276 %3 = select <2 x i1> %2, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 277 ret <2 x i32> %3 278} 279 280define i32 @test74(i32 %x) { 281; CHECK-LABEL: @test74( 282; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[X:%.*]], -1 283; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[TMP1]], i32 40, i32 42 284; CHECK-NEXT: ret i32 [[TMP2]] 285; 286 %1 = icmp sgt i32 %x, -1 287 %2 = select i1 %1, i32 40, i32 42 288 ret i32 %2 289} 290 291define <2 x i32> @test74vec(<2 x i32> %x) { 292; CHECK-LABEL: @test74vec( 293; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt <2 x i32> [[X:%.*]], <i32 -1, i32 -1> 294; CHECK-NEXT: [[TMP2:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 295; CHECK-NEXT: ret <2 x i32> [[TMP2]] 296; 297 %1 = icmp sgt <2 x i32> %x, <i32 -1, i32 -1> 298 %2 = select <2 x i1> %1, <2 x i32> <i32 40, i32 40>, <2 x i32> <i32 42, i32 42> 299 ret <2 x i32> %2 300} 301 302;; Code sequence for (X & 16) ? 16 : 0 303define i32 @test15a(i32 %X) { 304; CHECK-LABEL: @test15a( 305; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 16 306; CHECK-NEXT: ret i32 [[T1]] 307; 308 %t1 = and i32 %X, 16 309 %t2 = icmp eq i32 %t1, 0 310 %t3 = select i1 %t2, i32 0, i32 16 311 ret i32 %t3 312} 313 314;; Code sequence for (X & 32) ? 0 : 24 315define i32 @test15b(i32 %X) { 316; CHECK-LABEL: @test15b( 317; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 32 318; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[T1]], 32 319; CHECK-NEXT: ret i32 [[TMP1]] 320; 321 %t1 = and i32 %X, 32 322 %t2 = icmp eq i32 %t1, 0 323 %t3 = select i1 %t2, i32 32, i32 0 324 ret i32 %t3 325} 326 327;; Alternate code sequence for (X & 16) ? 16 : 0 328define i32 @test15c(i32 %X) { 329; CHECK-LABEL: @test15c( 330; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 16 331; CHECK-NEXT: ret i32 [[T1]] 332; 333 %t1 = and i32 %X, 16 334 %t2 = icmp eq i32 %t1, 16 335 %t3 = select i1 %t2, i32 16, i32 0 336 ret i32 %t3 337} 338 339;; Alternate code sequence for (X & 16) ? 16 : 0 340define i32 @test15d(i32 %X) { 341; CHECK-LABEL: @test15d( 342; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 16 343; CHECK-NEXT: ret i32 [[T1]] 344; 345 %t1 = and i32 %X, 16 346 %t2 = icmp ne i32 %t1, 0 347 %t3 = select i1 %t2, i32 16, i32 0 348 ret i32 %t3 349} 350 351;; (a & 128) ? 256 : 0 352define i32 @test15e(i32 %X) { 353; CHECK-LABEL: @test15e( 354; CHECK-NEXT: [[T1:%.*]] = shl i32 [[X:%.*]], 1 355; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T1]], 256 356; CHECK-NEXT: ret i32 [[TMP1]] 357; 358 %t1 = and i32 %X, 128 359 %t2 = icmp ne i32 %t1, 0 360 %t3 = select i1 %t2, i32 256, i32 0 361 ret i32 %t3 362} 363 364;; (a & 128) ? 0 : 256 365define i32 @test15f(i32 %X) { 366; CHECK-LABEL: @test15f( 367; CHECK-NEXT: [[T1:%.*]] = shl i32 [[X:%.*]], 1 368; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[T1]], 256 369; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP1]], 256 370; CHECK-NEXT: ret i32 [[TMP2]] 371; 372 %t1 = and i32 %X, 128 373 %t2 = icmp ne i32 %t1, 0 374 %t3 = select i1 %t2, i32 0, i32 256 375 ret i32 %t3 376} 377 378;; (a & 8) ? -1 : -9 379define i32 @test15g(i32 %X) { 380; CHECK-LABEL: @test15g( 381; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[X:%.*]], -9 382; CHECK-NEXT: ret i32 [[TMP1]] 383; 384 %t1 = and i32 %X, 8 385 %t2 = icmp ne i32 %t1, 0 386 %t3 = select i1 %t2, i32 -1, i32 -9 387 ret i32 %t3 388} 389 390;; (a & 8) ? -9 : -1 391define i32 @test15h(i32 %X) { 392; CHECK-LABEL: @test15h( 393; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8 394; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[T1]], -1 395; CHECK-NEXT: ret i32 [[TMP1]] 396; 397 %t1 = and i32 %X, 8 398 %t2 = icmp ne i32 %t1, 0 399 %t3 = select i1 %t2, i32 -9, i32 -1 400 ret i32 %t3 401} 402 403;; (a & 2) ? 577 : 1089 404define i32 @test15i(i32 %X) { 405; CHECK-LABEL: @test15i( 406; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 2 407; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 408; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i32 1089, i32 577 409; CHECK-NEXT: ret i32 [[T3]] 410; 411 %t1 = and i32 %X, 2 412 %t2 = icmp ne i32 %t1, 0 413 %t3 = select i1 %t2, i32 577, i32 1089 414 ret i32 %t3 415} 416 417;; (a & 2) ? 1089 : 577 418define i32 @test15j(i32 %X) { 419; CHECK-LABEL: @test15j( 420; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 2 421; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 422; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i32 577, i32 1089 423; CHECK-NEXT: ret i32 [[T3]] 424; 425 %t1 = and i32 %X, 2 426 %t2 = icmp ne i32 %t1, 0 427 %t3 = select i1 %t2, i32 1089, i32 577 428 ret i32 %t3 429} 430 431declare void @use1(i1) 432 433; (X & 8) == 0 ? -3 : -11 --> (X & 8) ^ -3 434; Extra cmp use ensures that cmp predicate canonicalization is thwarted. 435 436define i32 @clear_to_set(i32 %x) { 437; CHECK-LABEL: @clear_to_set( 438; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8 439; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 440; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[T1]], -3 441; CHECK-NEXT: call void @use1(i1 [[T2]]) 442; CHECK-NEXT: ret i32 [[TMP1]] 443; 444 %t1 = and i32 %x, 8 445 %t2 = icmp eq i32 %t1, 0 446 %t3 = select i1 %t2, i32 -3, i32 -11 447 call void @use1(i1 %t2) 448 ret i32 %t3 449} 450 451; (X & 8) == 0 ? -11 : -3 --> (X & 8) | -11 452; Extra cmp use ensures that cmp predicate canonicalization is thwarted. 453 454define i32 @clear_to_clear(i32 %x) { 455; CHECK-LABEL: @clear_to_clear( 456; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8 457; CHECK-NEXT: [[T2:%.*]] = icmp eq i32 [[T1]], 0 458; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T1]], -11 459; CHECK-NEXT: call void @use1(i1 [[T2]]) 460; CHECK-NEXT: ret i32 [[TMP1]] 461; 462 %t1 = and i32 %x, 8 463 %t2 = icmp eq i32 %t1, 0 464 %t3 = select i1 %t2, i32 -11, i32 -3 465 call void @use1(i1 %t2) 466 ret i32 %t3 467} 468 469; (X & 8) != 0 ? -3 : -11 --> (X & 8) | -11 470; Extra cmp use ensures that cmp predicate canonicalization is thwarted. 471 472define i32 @set_to_set(i32 %x) { 473; CHECK-LABEL: @set_to_set( 474; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8 475; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0 476; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[T1]], -11 477; CHECK-NEXT: call void @use1(i1 [[T2]]) 478; CHECK-NEXT: ret i32 [[TMP1]] 479; 480 %t1 = and i32 %x, 8 481 %t2 = icmp ne i32 %t1, 0 482 %t3 = select i1 %t2, i32 -3, i32 -11 483 call void @use1(i1 %t2) 484 ret i32 %t3 485} 486 487; (X & 8) != 0 ? -3 : -11 --> (X & 8) ^ -3 488; Extra cmp use ensures that cmp predicate canonicalization is thwarted. 489 490define i32 @set_to_clear(i32 %x) { 491; CHECK-LABEL: @set_to_clear( 492; CHECK-NEXT: [[T1:%.*]] = and i32 [[X:%.*]], 8 493; CHECK-NEXT: [[T2:%.*]] = icmp ne i32 [[T1]], 0 494; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[T1]], -3 495; CHECK-NEXT: call void @use1(i1 [[T2]]) 496; CHECK-NEXT: ret i32 [[TMP1]] 497; 498 %t1 = and i32 %x, 8 499 %t2 = icmp ne i32 %t1, 0 500 %t3 = select i1 %t2, i32 -11, i32 -3 501 call void @use1(i1 %t2) 502 ret i32 %t3 503} 504 505; (X & 128) == 0 ? 131 : 3 --> (X & 128) ^ 131 506 507define i8 @clear_to_set_decomposebittest(i8 %x) { 508; CHECK-LABEL: @clear_to_set_decomposebittest( 509; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128 510; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[TMP1]], -125 511; CHECK-NEXT: ret i8 [[TMP2]] 512; 513 %t2 = icmp sgt i8 %x, -1 514 %t3 = select i1 %t2, i8 131, i8 3 515 ret i8 %t3 516} 517 518; (X & 128) == 0 ? 3 : 131 --> (X & 128) | 3 519 520define i8 @clear_to_clear_decomposebittest(i8 %x) { 521; CHECK-LABEL: @clear_to_clear_decomposebittest( 522; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128 523; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], 3 524; CHECK-NEXT: ret i8 [[TMP2]] 525; 526 %t2 = icmp sgt i8 %x, -1 527 %t3 = select i1 %t2, i8 3, i8 131 528 ret i8 %t3 529} 530 531; (X & 128) != 0 ? 131 : 3 --> (X & 128) | 3 532 533define i8 @set_to_set_decomposebittest(i8 %x) { 534; CHECK-LABEL: @set_to_set_decomposebittest( 535; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128 536; CHECK-NEXT: [[TMP2:%.*]] = or i8 [[TMP1]], 3 537; CHECK-NEXT: ret i8 [[TMP2]] 538; 539 %t2 = icmp slt i8 %x, 0 540 %t3 = select i1 %t2, i8 131, i8 3 541 ret i8 %t3 542} 543 544; (X & 128) != 0 ? 3 : 131 --> (X & 128) ^ 131 545 546define i8 @set_to_clear_decomposebittest(i8 %x) { 547; CHECK-LABEL: @set_to_clear_decomposebittest( 548; CHECK-NEXT: [[TMP1:%.*]] = and i8 [[X:%.*]], -128 549; CHECK-NEXT: [[TMP2:%.*]] = xor i8 [[TMP1]], -125 550; CHECK-NEXT: ret i8 [[TMP2]] 551; 552 %t2 = icmp slt i8 %x, 0 553 %t3 = select i1 %t2, i8 3, i8 131 554 ret i8 %t3 555} 556 557; (X & 128) == 0 ? 131 : 3 --> (X & 128) ^ 131 558; Extra cmp use to verify that we are not creating extra instructions. 559 560define i8 @clear_to_set_decomposebittest_extra_use(i8 %x) { 561; CHECK-LABEL: @clear_to_set_decomposebittest_extra_use( 562; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[X:%.*]], -1 563; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 -125, i8 3 564; CHECK-NEXT: call void @use1(i1 [[T2]]) 565; CHECK-NEXT: ret i8 [[T3]] 566; 567 %t2 = icmp sgt i8 %x, -1 568 %t3 = select i1 %t2, i8 131, i8 3 569 call void @use1(i1 %t2) 570 ret i8 %t3 571} 572 573; (X & 128) == 0 ? 3 : 131 --> (X & 128) | 3 574; Extra cmp use to verify that we are not creating extra instructions. 575 576define i8 @clear_to_clear_decomposebittest_extra_use(i8 %x) { 577; CHECK-LABEL: @clear_to_clear_decomposebittest_extra_use( 578; CHECK-NEXT: [[T2:%.*]] = icmp sgt i8 [[X:%.*]], -1 579; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 3, i8 -125 580; CHECK-NEXT: call void @use1(i1 [[T2]]) 581; CHECK-NEXT: ret i8 [[T3]] 582; 583 %t2 = icmp sgt i8 %x, -1 584 %t3 = select i1 %t2, i8 3, i8 131 585 call void @use1(i1 %t2) 586 ret i8 %t3 587} 588 589; (X & 128) != 0 ? 131 : 3 --> (X & 128) | 3 590; Extra cmp use to verify that we are not creating extra instructions. 591 592define i8 @set_to_set_decomposebittest_extra_use(i8 %x) { 593; CHECK-LABEL: @set_to_set_decomposebittest_extra_use( 594; CHECK-NEXT: [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0 595; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 -125, i8 3 596; CHECK-NEXT: call void @use1(i1 [[T2]]) 597; CHECK-NEXT: ret i8 [[T3]] 598; 599 %t2 = icmp slt i8 %x, 0 600 %t3 = select i1 %t2, i8 131, i8 3 601 call void @use1(i1 %t2) 602 ret i8 %t3 603} 604 605; (X & 128) != 0 ? 3 : 131 --> (X & 128) ^ 131 606; Extra cmp use to verify that we are not creating extra instructions. 607 608define i8 @set_to_clear_decomposebittest_extra_use(i8 %x) { 609; CHECK-LABEL: @set_to_clear_decomposebittest_extra_use( 610; CHECK-NEXT: [[T2:%.*]] = icmp slt i8 [[X:%.*]], 0 611; CHECK-NEXT: [[T3:%.*]] = select i1 [[T2]], i8 3, i8 -125 612; CHECK-NEXT: call void @use1(i1 [[T2]]) 613; CHECK-NEXT: ret i8 [[T3]] 614; 615 %t2 = icmp slt i8 %x, 0 616 %t3 = select i1 %t2, i8 3, i8 131 617 call void @use1(i1 %t2) 618 ret i8 %t3 619} 620 621