1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py 2; RUN: opt < %s -instcombine -S | FileCheck %s 3 4define i64 @rem_signed(i64 %x1, i64 %y2) { 5; CHECK-LABEL: @rem_signed( 6; CHECK-NEXT: [[TMP1:%.*]] = srem i64 [[X1:%.*]], [[Y2:%.*]] 7; CHECK-NEXT: ret i64 [[TMP1]] 8; 9 %r = sdiv i64 %x1, %y2 10 %r7 = mul i64 %r, %y2 11 %r8 = sub i64 %x1, %r7 12 ret i64 %r8 13} 14 15define <4 x i32> @rem_signed_vec(<4 x i32> %t, <4 x i32> %u) { 16; CHECK-LABEL: @rem_signed_vec( 17; CHECK-NEXT: [[TMP1:%.*]] = srem <4 x i32> [[T:%.*]], [[U:%.*]] 18; CHECK-NEXT: ret <4 x i32> [[TMP1]] 19; 20 %k = sdiv <4 x i32> %t, %u 21 %l = mul <4 x i32> %k, %u 22 %m = sub <4 x i32> %t, %l 23 ret <4 x i32> %m 24} 25 26define i64 @rem_unsigned(i64 %x1, i64 %y2) { 27; CHECK-LABEL: @rem_unsigned( 28; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[X1:%.*]], [[Y2:%.*]] 29; CHECK-NEXT: ret i64 [[TMP1]] 30; 31 %r = udiv i64 %x1, %y2 32 %r7 = mul i64 %r, %y2 33 %r8 = sub i64 %x1, %r7 34 ret i64 %r8 35} 36 37; PR28672 - https://llvm.org/bugs/show_bug.cgi?id=28672 38 39define i8 @big_divisor(i8 %x) { 40; CHECK-LABEL: @big_divisor( 41; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X:%.*]], -127 42; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X]], 127 43; CHECK-NEXT: [[REM:%.*]] = select i1 [[TMP1]], i8 [[X]], i8 [[TMP2]] 44; CHECK-NEXT: ret i8 [[REM]] 45; 46 %rem = urem i8 %x, 129 47 ret i8 %rem 48} 49 50define i5 @biggest_divisor(i5 %x) { 51; CHECK-LABEL: @biggest_divisor( 52; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i5 [[X:%.*]], -1 53; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i5 54; CHECK-NEXT: [[REM:%.*]] = add i5 [[TMP2]], [[X]] 55; CHECK-NEXT: ret i5 [[REM]] 56; 57 %rem = urem i5 %x, -1 58 ret i5 %rem 59} 60 61define i8 @urem_with_sext_bool_divisor(i1 %x, i8 %y) { 62; CHECK-LABEL: @urem_with_sext_bool_divisor( 63; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y:%.*]], -1 64; CHECK-NEXT: [[REM:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y]] 65; CHECK-NEXT: ret i8 [[REM]] 66; 67 %s = sext i1 %x to i8 68 %rem = urem i8 %y, %s 69 ret i8 %rem 70} 71 72define <2 x i8> @urem_with_sext_bool_divisor_vec(<2 x i1> %x, <2 x i8> %y) { 73; CHECK-LABEL: @urem_with_sext_bool_divisor_vec( 74; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[Y:%.*]], <i8 -1, i8 -1> 75; CHECK-NEXT: [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> zeroinitializer, <2 x i8> [[Y]] 76; CHECK-NEXT: ret <2 x i8> [[REM]] 77; 78 %s = sext <2 x i1> %x to <2 x i8> 79 %rem = urem <2 x i8> %y, %s 80 ret <2 x i8> %rem 81} 82 83define <2 x i4> @big_divisor_vec(<2 x i4> %x) { 84; CHECK-LABEL: @big_divisor_vec( 85; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i4> [[X:%.*]], <i4 -3, i4 -3> 86; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i4> [[X]], <i4 3, i4 3> 87; CHECK-NEXT: [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i4> [[X]], <2 x i4> [[TMP2]] 88; CHECK-NEXT: ret <2 x i4> [[REM]] 89; 90 %rem = urem <2 x i4> %x, <i4 13, i4 13> 91 ret <2 x i4> %rem 92} 93 94define i8 @urem1(i8 %x, i8 %y) { 95; CHECK-LABEL: @urem1( 96; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]] 97; CHECK-NEXT: ret i8 [[TMP1]] 98; 99 %A = udiv i8 %x, %y 100 %B = mul i8 %A, %y 101 %C = sub i8 %x, %B 102 ret i8 %C 103} 104 105define i8 @srem1(i8 %x, i8 %y) { 106; CHECK-LABEL: @srem1( 107; CHECK-NEXT: [[TMP1:%.*]] = srem i8 [[X:%.*]], [[Y:%.*]] 108; CHECK-NEXT: ret i8 [[TMP1]] 109; 110 %A = sdiv i8 %x, %y 111 %B = mul i8 %A, %y 112 %C = sub i8 %x, %B 113 ret i8 %C 114} 115 116define i8 @urem2(i8 %x, i8 %y) { 117; CHECK-LABEL: @urem2( 118; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X:%.*]], [[Y:%.*]] 119; CHECK-NEXT: [[C:%.*]] = sub i8 0, [[TMP1]] 120; CHECK-NEXT: ret i8 [[C]] 121; 122 %A = udiv i8 %x, %y 123 %B = mul i8 %A, %y 124 %C = sub i8 %B, %x 125 ret i8 %C 126} 127 128define i8 @urem3(i8 %x) { 129; CHECK-LABEL: @urem3( 130; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X:%.*]], 3 131; CHECK-NEXT: [[B1:%.*]] = sub i8 [[X]], [[TMP1]] 132; CHECK-NEXT: [[C:%.*]] = add i8 [[B1]], [[X]] 133; CHECK-NEXT: ret i8 [[C]] 134; 135 %A = udiv i8 %x, 3 136 %B = mul i8 %A, -3 137 %C = sub i8 %x, %B 138 ret i8 %C 139} 140 141; (((X / Y) * Y) / Y) -> X / Y 142 143define i32 @sdiv_mul_sdiv(i32 %x, i32 %y) { 144; CHECK-LABEL: @sdiv_mul_sdiv( 145; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[X:%.*]], [[Y:%.*]] 146; CHECK-NEXT: ret i32 [[R]] 147; 148 %div = sdiv i32 %x, %y 149 %mul = mul i32 %div, %y 150 %r = sdiv i32 %mul, %y 151 ret i32 %r 152} 153 154; (((X / Y) * Y) / Y) -> X / Y 155 156define i32 @udiv_mul_udiv(i32 %x, i32 %y) { 157; CHECK-LABEL: @udiv_mul_udiv( 158; CHECK-NEXT: [[R:%.*]] = udiv i32 [[X:%.*]], [[Y:%.*]] 159; CHECK-NEXT: ret i32 [[R]] 160; 161 %div = udiv i32 %x, %y 162 %mul = mul i32 %div, %y 163 %r = udiv i32 %mul, %y 164 ret i32 %r 165} 166 167define i32 @test1(i32 %A) { 168; CHECK-LABEL: @test1( 169; CHECK-NEXT: ret i32 0 170; 171 %B = srem i32 %A, 1 ; ISA constant 0 172 ret i32 %B 173} 174 175define i32 @test3(i32 %A) { 176; CHECK-LABEL: @test3( 177; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], 7 178; CHECK-NEXT: ret i32 [[B]] 179; 180 %B = urem i32 %A, 8 181 ret i32 %B 182} 183 184define <2 x i32> @vec_power_of_2_constant_splat_divisor(<2 x i32> %A) { 185; CHECK-LABEL: @vec_power_of_2_constant_splat_divisor( 186; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A:%.*]], <i32 7, i32 7> 187; CHECK-NEXT: ret <2 x i32> [[B]] 188; 189 %B = urem <2 x i32> %A, <i32 8, i32 8> 190 ret <2 x i32> %B 191} 192 193define <2 x i19> @weird_vec_power_of_2_constant_splat_divisor(<2 x i19> %A) { 194; CHECK-LABEL: @weird_vec_power_of_2_constant_splat_divisor( 195; CHECK-NEXT: [[B:%.*]] = and <2 x i19> [[A:%.*]], <i19 7, i19 7> 196; CHECK-NEXT: ret <2 x i19> [[B]] 197; 198 %B = urem <2 x i19> %A, <i19 8, i19 8> 199 ret <2 x i19> %B 200} 201 202define i1 @test3a(i32 %A) { 203; CHECK-LABEL: @test3a( 204; CHECK-NEXT: [[B1:%.*]] = and i32 [[A:%.*]], 7 205; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[B1]], 0 206; CHECK-NEXT: ret i1 [[C]] 207; 208 %B = srem i32 %A, -8 209 %C = icmp ne i32 %B, 0 210 ret i1 %C 211} 212 213define <2 x i1> @test3a_vec(<2 x i32> %A) { 214; CHECK-LABEL: @test3a_vec( 215; CHECK-NEXT: [[B1:%.*]] = and <2 x i32> [[A:%.*]], <i32 7, i32 7> 216; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[B1]], zeroinitializer 217; CHECK-NEXT: ret <2 x i1> [[C]] 218; 219 %B = srem <2 x i32> %A, <i32 -8, i32 -8> 220 %C = icmp ne <2 x i32> %B, zeroinitializer 221 ret <2 x i1> %C 222} 223 224define i32 @test4(i32 %X, i1 %C) { 225; CHECK-LABEL: @test4( 226; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i32 0, i32 7 227; CHECK-NEXT: [[R:%.*]] = and i32 [[TMP1]], [[X:%.*]] 228; CHECK-NEXT: ret i32 [[R]] 229; 230 %V = select i1 %C, i32 1, i32 8 231 %R = urem i32 %X, %V 232 ret i32 %R 233} 234 235define i32 @test5(i32 %X, i8 %B) { 236; CHECK-LABEL: @test5( 237; CHECK-NEXT: [[SHIFT_UPGRD_1:%.*]] = zext i8 [[B:%.*]] to i32 238; CHECK-NEXT: [[AMT:%.*]] = shl nuw i32 32, [[SHIFT_UPGRD_1]] 239; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[AMT]], -1 240; CHECK-NEXT: [[V:%.*]] = and i32 [[TMP1]], [[X:%.*]] 241; CHECK-NEXT: ret i32 [[V]] 242; 243 %shift.upgrd.1 = zext i8 %B to i32 244 %Amt = shl i32 32, %shift.upgrd.1 245 %V = urem i32 %X, %Amt 246 ret i32 %V 247} 248 249define i32 @test6(i32 %A) { 250; CHECK-LABEL: @test6( 251; CHECK-NEXT: ret i32 undef 252; 253 %B = srem i32 %A, 0 ;; undef 254 ret i32 %B 255} 256 257define i32 @test7(i32 %A) { 258; CHECK-LABEL: @test7( 259; CHECK-NEXT: ret i32 0 260; 261 %B = mul i32 %A, 8 262 %C = srem i32 %B, 4 263 ret i32 %C 264} 265 266define i32 @test8(i32 %A) { 267; CHECK-LABEL: @test8( 268; CHECK-NEXT: ret i32 0 269; 270 %B = shl i32 %A, 4 271 %C = srem i32 %B, 8 272 ret i32 %C 273} 274 275define i32 @test9(i32 %A) { 276; CHECK-LABEL: @test9( 277; CHECK-NEXT: ret i32 0 278; 279 %B = mul i32 %A, 64 280 %C = urem i32 %B, 32 281 ret i32 %C 282} 283 284define i32 @test10(i8 %c) { 285; CHECK-LABEL: @test10( 286; CHECK-NEXT: ret i32 0 287; 288 %tmp.1 = zext i8 %c to i32 289 %tmp.2 = mul i32 %tmp.1, 4 290 %tmp.3 = sext i32 %tmp.2 to i64 291 %tmp.5 = urem i64 %tmp.3, 4 292 %tmp.6 = trunc i64 %tmp.5 to i32 293 ret i32 %tmp.6 294} 295 296define i32 @test11(i32 %i) { 297; CHECK-LABEL: @test11( 298; CHECK-NEXT: ret i32 0 299; 300 %tmp.1 = and i32 %i, -2 301 %tmp.3 = mul i32 %tmp.1, 2 302 %tmp.5 = urem i32 %tmp.3, 4 303 ret i32 %tmp.5 304} 305 306define i32 @test12(i32 %i) { 307; CHECK-LABEL: @test12( 308; CHECK-NEXT: ret i32 0 309; 310 %tmp.1 = and i32 %i, -4 311 %tmp.5 = srem i32 %tmp.1, 2 312 ret i32 %tmp.5 313} 314 315define i32 @test13(i32 %i) { 316; CHECK-LABEL: @test13( 317; CHECK-NEXT: ret i32 0 318; 319 %x = srem i32 %i, %i 320 ret i32 %x 321} 322 323define i64 @test14(i64 %x, i32 %y) { 324; CHECK-LABEL: @test14( 325; CHECK-NEXT: [[SHL:%.*]] = shl i32 1, [[Y:%.*]] 326; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64 327; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[ZEXT]], -1 328; CHECK-NEXT: [[UREM:%.*]] = and i64 [[TMP1]], [[X:%.*]] 329; CHECK-NEXT: ret i64 [[UREM]] 330; 331 %shl = shl i32 1, %y 332 %zext = zext i32 %shl to i64 333 %urem = urem i64 %x, %zext 334 ret i64 %urem 335} 336 337define i64 @test15(i32 %x, i32 %y) { 338; CHECK-LABEL: @test15( 339; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i32 -1, [[Y:%.*]] 340; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[NOTMASK]], -1 341; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[TMP1]], [[X:%.*]] 342; CHECK-NEXT: [[UREM:%.*]] = zext i32 [[TMP2]] to i64 343; CHECK-NEXT: ret i64 [[UREM]] 344; 345 %shl = shl i32 1, %y 346 %zext0 = zext i32 %shl to i64 347 %zext1 = zext i32 %x to i64 348 %urem = urem i64 %zext1, %zext0 349 ret i64 %urem 350} 351 352define i32 @test16(i32 %x, i32 %y) { 353; CHECK-LABEL: @test16( 354; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[Y:%.*]], 11 355; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 4 356; CHECK-NEXT: [[TMP1:%.*]] = or i32 [[AND]], 3 357; CHECK-NEXT: [[REM:%.*]] = and i32 [[TMP1]], [[X:%.*]] 358; CHECK-NEXT: ret i32 [[REM]] 359; 360 %shr = lshr i32 %y, 11 361 %and = and i32 %shr, 4 362 %add = add i32 %and, 4 363 %rem = urem i32 %x, %add 364 ret i32 %rem 365} 366 367define i32 @test17(i32 %X) { 368; CHECK-LABEL: @test17( 369; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 1 370; CHECK-NEXT: [[TMP2:%.*]] = zext i1 [[TMP1]] to i32 371; CHECK-NEXT: ret i32 [[TMP2]] 372; 373 %A = urem i32 1, %X 374 ret i32 %A 375} 376 377define i32 @test18(i16 %x, i32 %y) { 378; CHECK-LABEL: @test18( 379; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], 4 380; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i16 [[TMP1]], 0 381; CHECK-NEXT: [[TMP3:%.*]] = select i1 [[TMP2]], i32 63, i32 31 382; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], [[Y:%.*]] 383; CHECK-NEXT: ret i32 [[TMP4]] 384; 385 %1 = and i16 %x, 4 386 %2 = icmp ne i16 %1, 0 387 %3 = select i1 %2, i32 32, i32 64 388 %4 = urem i32 %y, %3 389 ret i32 %4 390} 391 392define i32 @test19(i32 %x, i32 %y) { 393; CHECK-LABEL: @test19( 394; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]] 395; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]] 396; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], [[B]] 397; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A]] 398; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1 399; CHECK-NEXT: [[E:%.*]] = and i32 [[TMP1]], [[Y]] 400; CHECK-NEXT: ret i32 [[E]] 401; 402 %A = shl i32 1, %x 403 %B = shl i32 1, %y 404 %C = and i32 %A, %B 405 %D = add i32 %C, %A 406 %E = urem i32 %y, %D 407 ret i32 %E 408} 409 410define i32 @test19_commutative0(i32 %x, i32 %y) { 411; CHECK-LABEL: @test19_commutative0( 412; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]] 413; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]] 414; CHECK-NEXT: [[C:%.*]] = and i32 [[B]], [[A]] 415; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A]] 416; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1 417; CHECK-NEXT: [[E:%.*]] = and i32 [[TMP1]], [[Y]] 418; CHECK-NEXT: ret i32 [[E]] 419; 420 %A = shl i32 1, %x 421 %B = shl i32 1, %y 422 %C = and i32 %B, %A ; swapped 423 %D = add i32 %C, %A 424 %E = urem i32 %y, %D 425 ret i32 %E 426} 427 428define i32 @test19_commutative1(i32 %x, i32 %y) { 429; CHECK-LABEL: @test19_commutative1( 430; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]] 431; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]] 432; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], [[B]] 433; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]] 434; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1 435; CHECK-NEXT: [[E:%.*]] = and i32 [[TMP1]], [[Y]] 436; CHECK-NEXT: ret i32 [[E]] 437; 438 %A = shl i32 1, %x 439 %B = shl i32 1, %y 440 %C = and i32 %A, %B 441 %D = add i32 %A, %C ; swapped 442 %E = urem i32 %y, %D 443 ret i32 %E 444} 445 446define i32 @test19_commutative2(i32 %x, i32 %y) { 447; CHECK-LABEL: @test19_commutative2( 448; CHECK-NEXT: [[A:%.*]] = shl i32 1, [[X:%.*]] 449; CHECK-NEXT: [[B:%.*]] = shl i32 1, [[Y:%.*]] 450; CHECK-NEXT: [[C:%.*]] = and i32 [[B]], [[A]] 451; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]] 452; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1 453; CHECK-NEXT: [[E:%.*]] = and i32 [[TMP1]], [[Y]] 454; CHECK-NEXT: ret i32 [[E]] 455; 456 %A = shl i32 1, %x 457 %B = shl i32 1, %y 458 %C = and i32 %B, %A ; swapped 459 %D = add i32 %A, %C ; swapped 460 %E = urem i32 %y, %D 461 ret i32 %E 462} 463 464define <2 x i64> @test20(<2 x i64> %X, <2 x i1> %C) { 465; CHECK-LABEL: @test20( 466; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer 467; CHECK-NEXT: ret <2 x i64> [[R]] 468; 469 %V = select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8, i64 9> 470 %R = urem <2 x i64> %V, <i64 2, i64 3> 471 ret <2 x i64> %R 472} 473 474define i32 @test21(i1 %c0, i32* %p) { 475; CHECK-LABEL: @test21( 476; CHECK-NEXT: entry: 477; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 478; CHECK: if.then: 479; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4 480; CHECK-NEXT: [[PHITMP:%.*]] = srem i32 [[V]], 5 481; CHECK-NEXT: br label [[IF_END]] 482; CHECK: if.end: 483; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[PHITMP]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ] 484; CHECK-NEXT: ret i32 [[LHS]] 485; 486entry: 487 br i1 %c0, label %if.then, label %if.end 488 489if.then: 490 %v = load volatile i32, i32* %p 491 br label %if.end 492 493if.end: 494 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ] 495 %rem = srem i32 %lhs, 5 496 ret i32 %rem 497} 498 499@a = common global [5 x i16] zeroinitializer, align 2 500@b = common global i16 0, align 2 501 502define i32 @pr27968_0(i1 %c0, i32* %p) { 503; CHECK-LABEL: @pr27968_0( 504; CHECK-NEXT: entry: 505; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 506; CHECK: if.then: 507; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4 508; CHECK-NEXT: br label [[IF_END]] 509; CHECK: if.end: 510; CHECK-NEXT: br i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b), label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]] 511; CHECK: rem.is.safe: 512; CHECK-NEXT: ret i32 0 513; CHECK: rem.is.unsafe: 514; CHECK-NEXT: ret i32 0 515; 516entry: 517 br i1 %c0, label %if.then, label %if.end 518 519if.then: 520 %v = load volatile i32, i32* %p 521 br label %if.end 522 523if.end: 524 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ] 525 br i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b), label %rem.is.safe, label %rem.is.unsafe 526 527rem.is.safe: 528 %rem = srem i32 %lhs, zext (i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b) to i32) 529 ret i32 %rem 530 531rem.is.unsafe: 532 ret i32 0 533} 534 535define i32 @pr27968_1(i1 %c0, i1 %always_false, i32* %p) { 536; CHECK-LABEL: @pr27968_1( 537; CHECK-NEXT: entry: 538; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 539; CHECK: if.then: 540; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4 541; CHECK-NEXT: br label [[IF_END]] 542; CHECK: if.end: 543; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[V]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ] 544; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]] 545; CHECK: rem.is.safe: 546; CHECK-NEXT: [[REM:%.*]] = srem i32 [[LHS]], -2147483648 547; CHECK-NEXT: ret i32 [[REM]] 548; CHECK: rem.is.unsafe: 549; CHECK-NEXT: ret i32 0 550; 551entry: 552 br i1 %c0, label %if.then, label %if.end 553 554if.then: 555 %v = load volatile i32, i32* %p 556 br label %if.end 557 558if.end: 559 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ] 560 br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe 561 562rem.is.safe: 563 %rem = srem i32 %lhs, -2147483648 564 ret i32 %rem 565 566rem.is.unsafe: 567 ret i32 0 568} 569 570define i32 @pr27968_2(i1 %c0, i32* %p) { 571; CHECK-LABEL: @pr27968_2( 572; CHECK-NEXT: entry: 573; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 574; CHECK: if.then: 575; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4 576; CHECK-NEXT: br label [[IF_END]] 577; CHECK: if.end: 578; CHECK-NEXT: br i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b), label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]] 579; CHECK: rem.is.safe: 580; CHECK-NEXT: ret i32 0 581; CHECK: rem.is.unsafe: 582; CHECK-NEXT: ret i32 0 583; 584entry: 585 br i1 %c0, label %if.then, label %if.end 586 587if.then: 588 %v = load volatile i32, i32* %p 589 br label %if.end 590 591if.end: 592 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ] 593 br i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b), label %rem.is.safe, label %rem.is.unsafe 594 595rem.is.safe: 596 %rem = urem i32 %lhs, zext (i1 icmp eq (i16* getelementptr inbounds ([5 x i16], [5 x i16]* @a, i64 0, i64 4), i16* @b) to i32) 597 ret i32 %rem 598 599rem.is.unsafe: 600 ret i32 0 601} 602 603define i32 @pr27968_3(i1 %c0, i1 %always_false, i32* %p) { 604; CHECK-LABEL: @pr27968_3( 605; CHECK-NEXT: entry: 606; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]] 607; CHECK: if.then: 608; CHECK-NEXT: [[V:%.*]] = load volatile i32, i32* [[P:%.*]], align 4 609; CHECK-NEXT: [[PHITMP:%.*]] = and i32 [[V]], 2147483647 610; CHECK-NEXT: br label [[IF_END]] 611; CHECK: if.end: 612; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[PHITMP]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ] 613; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]] 614; CHECK: rem.is.safe: 615; CHECK-NEXT: ret i32 [[LHS]] 616; CHECK: rem.is.unsafe: 617; CHECK-NEXT: ret i32 0 618; 619entry: 620 br i1 %c0, label %if.then, label %if.end 621 622if.then: 623 %v = load volatile i32, i32* %p 624 br label %if.end 625 626if.end: 627 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ] 628 br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe 629 630rem.is.safe: 631 %rem = urem i32 %lhs, -2147483648 632 ret i32 %rem 633 634rem.is.unsafe: 635 ret i32 0 636} 637 638define i32 @test22(i32 %A) { 639; CHECK-LABEL: @test22( 640; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 2147483647 641; CHECK-NEXT: [[MUL:%.*]] = urem i32 [[AND]], 2147483647 642; CHECK-NEXT: ret i32 [[MUL]] 643; 644 %and = and i32 %A, 2147483647 645 %mul = srem i32 %and, 2147483647 646 ret i32 %mul 647} 648 649define <2 x i32> @test23(<2 x i32> %A) { 650; CHECK-LABEL: @test23( 651; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], <i32 2147483647, i32 2147483647> 652; CHECK-NEXT: [[MUL:%.*]] = urem <2 x i32> [[AND]], <i32 2147483647, i32 2147483647> 653; CHECK-NEXT: ret <2 x i32> [[MUL]] 654; 655 %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647> 656 %mul = srem <2 x i32> %and, <i32 2147483647, i32 2147483647> 657 ret <2 x i32> %mul 658} 659 660; FP division-by-zero is not UB. 661 662define double @PR34870(i1 %cond, double %x, double %y) { 663; CHECK-LABEL: @PR34870( 664; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], double [[Y:%.*]], double 0.000000e+00 665; CHECK-NEXT: [[FMOD:%.*]] = frem double [[X:%.*]], [[SEL]] 666; CHECK-NEXT: ret double [[FMOD]] 667; 668 %sel = select i1 %cond, double %y, double 0.0 669 %fmod = frem double %x, %sel 670 ret double %fmod 671} 672 673