1180 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4declare void @use(i32)5 6define i64 @rem_signed(i64 %x1, i64 %y2) {7; CHECK-LABEL: @rem_signed(8; CHECK-NEXT: [[X1_FR:%.*]] = freeze i64 [[X1:%.*]]9; CHECK-NEXT: [[TMP1:%.*]] = srem i64 [[X1_FR]], [[Y2:%.*]]10; CHECK-NEXT: ret i64 [[TMP1]]11;12 %r = sdiv i64 %x1, %y213 %r7 = mul i64 %r, %y214 %r8 = sub i64 %x1, %r715 ret i64 %r816}17 18define <4 x i32> @rem_signed_vec(<4 x i32> %t, <4 x i32> %u) {19; CHECK-LABEL: @rem_signed_vec(20; CHECK-NEXT: [[T_FR:%.*]] = freeze <4 x i32> [[T:%.*]]21; CHECK-NEXT: [[TMP1:%.*]] = srem <4 x i32> [[T_FR]], [[U:%.*]]22; CHECK-NEXT: ret <4 x i32> [[TMP1]]23;24 %k = sdiv <4 x i32> %t, %u25 %l = mul <4 x i32> %k, %u26 %m = sub <4 x i32> %t, %l27 ret <4 x i32> %m28}29 30define i64 @rem_unsigned(i64 %x1, i64 %y2) {31; CHECK-LABEL: @rem_unsigned(32; CHECK-NEXT: [[X1_FR:%.*]] = freeze i64 [[X1:%.*]]33; CHECK-NEXT: [[TMP1:%.*]] = urem i64 [[X1_FR]], [[Y2:%.*]]34; CHECK-NEXT: ret i64 [[TMP1]]35;36 %r = udiv i64 %x1, %y237 %r7 = mul i64 %r, %y238 %r8 = sub i64 %x1, %r739 ret i64 %r840}41 42; PR28672 - https://llvm.org/bugs/show_bug.cgi?id=2867243 44define i8 @big_divisor(i8 %x) {45; CHECK-LABEL: @big_divisor(46; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]47; CHECK-NEXT: [[TMP1:%.*]] = icmp ult i8 [[X_FR]], -12748; CHECK-NEXT: [[TMP2:%.*]] = add i8 [[X_FR]], 12749; CHECK-NEXT: [[REM:%.*]] = select i1 [[TMP1]], i8 [[X_FR]], i8 [[TMP2]]50; CHECK-NEXT: ret i8 [[REM]]51;52 %rem = urem i8 %x, 12953 ret i8 %rem54}55 56define i5 @biggest_divisor(i5 %x) {57; CHECK-LABEL: @biggest_divisor(58; CHECK-NEXT: [[X_FR:%.*]] = freeze i5 [[X:%.*]]59; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i5 [[X_FR]], -160; CHECK-NEXT: [[REM:%.*]] = select i1 [[DOTNOT]], i5 0, i5 [[X_FR]]61; CHECK-NEXT: ret i5 [[REM]]62;63 %rem = urem i5 %x, -164 ret i5 %rem65}66 67define i8 @urem_with_sext_bool_divisor(i1 %x, i8 %y) {68; CHECK-LABEL: @urem_with_sext_bool_divisor(69; CHECK-NEXT: [[Y_FROZEN:%.*]] = freeze i8 [[Y:%.*]]70; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i8 [[Y_FROZEN]], -171; CHECK-NEXT: [[REM:%.*]] = select i1 [[TMP1]], i8 0, i8 [[Y_FROZEN]]72; CHECK-NEXT: ret i8 [[REM]]73;74 %s = sext i1 %x to i875 %rem = urem i8 %y, %s76 ret i8 %rem77}78 79define <2 x i8> @urem_with_sext_bool_divisor_vec(<2 x i1> %x, <2 x i8> %y) {80; CHECK-LABEL: @urem_with_sext_bool_divisor_vec(81; CHECK-NEXT: [[Y_FROZEN:%.*]] = freeze <2 x i8> [[Y:%.*]]82; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i8> [[Y_FROZEN]], splat (i8 -1)83; CHECK-NEXT: [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i8> zeroinitializer, <2 x i8> [[Y_FROZEN]]84; CHECK-NEXT: ret <2 x i8> [[REM]]85;86 %s = sext <2 x i1> %x to <2 x i8>87 %rem = urem <2 x i8> %y, %s88 ret <2 x i8> %rem89}90 91define <2 x i4> @big_divisor_vec(<2 x i4> %x) {92; CHECK-LABEL: @big_divisor_vec(93; CHECK-NEXT: [[X_FR:%.*]] = freeze <2 x i4> [[X:%.*]]94; CHECK-NEXT: [[TMP1:%.*]] = icmp ult <2 x i4> [[X_FR]], splat (i4 -3)95; CHECK-NEXT: [[TMP2:%.*]] = add <2 x i4> [[X_FR]], splat (i4 3)96; CHECK-NEXT: [[REM:%.*]] = select <2 x i1> [[TMP1]], <2 x i4> [[X_FR]], <2 x i4> [[TMP2]]97; CHECK-NEXT: ret <2 x i4> [[REM]]98;99 %rem = urem <2 x i4> %x, <i4 13, i4 13>100 ret <2 x i4> %rem101}102 103define i8 @urem1(i8 %x, i8 %y) {104; CHECK-LABEL: @urem1(105; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]106; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X_FR]], [[Y:%.*]]107; CHECK-NEXT: ret i8 [[TMP1]]108;109 %A = udiv i8 %x, %y110 %B = mul i8 %A, %y111 %C = sub i8 %x, %B112 ret i8 %C113}114 115define i8 @srem1(i8 %x, i8 %y) {116; CHECK-LABEL: @srem1(117; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]118; CHECK-NEXT: [[TMP1:%.*]] = srem i8 [[X_FR]], [[Y:%.*]]119; CHECK-NEXT: ret i8 [[TMP1]]120;121 %A = sdiv i8 %x, %y122 %B = mul i8 %A, %y123 %C = sub i8 %x, %B124 ret i8 %C125}126 127define i8 @urem2(i8 %x, i8 %y) {128; CHECK-LABEL: @urem2(129; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]130; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X_FR]], [[Y:%.*]]131; CHECK-NEXT: [[C:%.*]] = sub i8 0, [[TMP1]]132; CHECK-NEXT: ret i8 [[C]]133;134 %A = udiv i8 %x, %y135 %B = mul i8 %A, %y136 %C = sub i8 %B, %x137 ret i8 %C138}139 140define i8 @urem3(i8 %x) {141; CHECK-LABEL: @urem3(142; CHECK-NEXT: [[X_FR:%.*]] = freeze i8 [[X:%.*]]143; CHECK-NEXT: [[TMP1:%.*]] = urem i8 [[X_FR]], 3144; CHECK-NEXT: [[B_NEG:%.*]] = sub nuw i8 [[X_FR]], [[TMP1]]145; CHECK-NEXT: [[C:%.*]] = add i8 [[B_NEG]], [[X_FR]]146; CHECK-NEXT: ret i8 [[C]]147;148 %A = udiv i8 %x, 3149 %B = mul i8 %A, -3150 %C = sub i8 %x, %B151 ret i8 %C152}153 154; (((X / Y) * Y) / Y) -> X / Y155 156define i32 @sdiv_mul_sdiv(i32 %x, i32 %y) {157; CHECK-LABEL: @sdiv_mul_sdiv(158; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]159; CHECK-NEXT: [[R:%.*]] = sdiv i32 [[X_FR]], [[Y:%.*]]160; CHECK-NEXT: ret i32 [[R]]161;162 %div = sdiv i32 %x, %y163 %mul = mul i32 %div, %y164 %r = sdiv i32 %mul, %y165 ret i32 %r166}167 168; (((X / Y) * Y) / Y) -> X / Y169 170define i32 @udiv_mul_udiv(i32 %x, i32 %y) {171; CHECK-LABEL: @udiv_mul_udiv(172; CHECK-NEXT: [[X_FR:%.*]] = freeze i32 [[X:%.*]]173; CHECK-NEXT: [[R:%.*]] = udiv i32 [[X_FR]], [[Y:%.*]]174; CHECK-NEXT: ret i32 [[R]]175;176 %div = udiv i32 %x, %y177 %mul = mul i32 %div, %y178 %r = udiv i32 %mul, %y179 ret i32 %r180}181 182define i32 @test1(i32 %A) {183; CHECK-LABEL: @test1(184; CHECK-NEXT: ret i32 0185;186 %B = srem i32 %A, 1 ; ISA constant 0187 ret i32 %B188}189 190define i32 @test3(i32 %A) {191; CHECK-LABEL: @test3(192; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], 7193; CHECK-NEXT: ret i32 [[B]]194;195 %B = urem i32 %A, 8196 ret i32 %B197}198 199define <2 x i32> @vec_power_of_2_constant_splat_divisor(<2 x i32> %A) {200; CHECK-LABEL: @vec_power_of_2_constant_splat_divisor(201; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 7)202; CHECK-NEXT: ret <2 x i32> [[B]]203;204 %B = urem <2 x i32> %A, <i32 8, i32 8>205 ret <2 x i32> %B206}207 208define <2 x i19> @weird_vec_power_of_2_constant_splat_divisor(<2 x i19> %A) {209; CHECK-LABEL: @weird_vec_power_of_2_constant_splat_divisor(210; CHECK-NEXT: [[B:%.*]] = and <2 x i19> [[A:%.*]], splat (i19 7)211; CHECK-NEXT: ret <2 x i19> [[B]]212;213 %B = urem <2 x i19> %A, <i19 8, i19 8>214 ret <2 x i19> %B215}216 217define i1 @test3a(i32 %A) {218; CHECK-LABEL: @test3a(219; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 7220; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[TMP1]], 0221; CHECK-NEXT: ret i1 [[C]]222;223 %B = srem i32 %A, -8224 %C = icmp ne i32 %B, 0225 ret i1 %C226}227 228define <2 x i1> @test3a_vec(<2 x i32> %A) {229; CHECK-LABEL: @test3a_vec(230; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 7)231; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer232; CHECK-NEXT: ret <2 x i1> [[C]]233;234 %B = srem <2 x i32> %A, <i32 -8, i32 -8>235 %C = icmp ne <2 x i32> %B, zeroinitializer236 ret <2 x i1> %C237}238 239define i32 @test4(i32 %X, i1 %C) {240; CHECK-LABEL: @test4(241; CHECK-NEXT: [[TMP1:%.*]] = select i1 [[C:%.*]], i32 0, i32 7242; CHECK-NEXT: [[R:%.*]] = and i32 [[X:%.*]], [[TMP1]]243; CHECK-NEXT: ret i32 [[R]]244;245 %V = select i1 %C, i32 1, i32 8246 %R = urem i32 %X, %V247 ret i32 %R248}249 250define i32 @test5(i32 %X, i8 %B) {251; CHECK-LABEL: @test5(252; CHECK-NEXT: [[SHIFT_UPGRD_1:%.*]] = zext nneg i8 [[B:%.*]] to i32253; CHECK-NEXT: [[AMT:%.*]] = shl nuw i32 32, [[SHIFT_UPGRD_1]]254; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[AMT]], -1255; CHECK-NEXT: [[V:%.*]] = and i32 [[X:%.*]], [[TMP1]]256; CHECK-NEXT: ret i32 [[V]]257;258 %shift.upgrd.1 = zext i8 %B to i32259 %Amt = shl i32 32, %shift.upgrd.1260 %V = urem i32 %X, %Amt261 ret i32 %V262}263 264define i32 @test6(i32 %A) {265; CHECK-LABEL: @test6(266; CHECK-NEXT: ret i32 poison267;268 %B = srem i32 %A, 0 ;; undef269 ret i32 %B270}271 272define i32 @test7(i32 %A) {273; CHECK-LABEL: @test7(274; CHECK-NEXT: ret i32 0275;276 %B = mul i32 %A, 8277 %C = srem i32 %B, 4278 ret i32 %C279}280 281define i32 @test8(i32 %A) {282; CHECK-LABEL: @test8(283; CHECK-NEXT: ret i32 0284;285 %B = shl i32 %A, 4286 %C = srem i32 %B, 8287 ret i32 %C288}289 290define i32 @test9(i32 %A) {291; CHECK-LABEL: @test9(292; CHECK-NEXT: ret i32 0293;294 %B = mul i32 %A, 64295 %C = urem i32 %B, 32296 ret i32 %C297}298 299define i32 @test10(i8 %c) {300; CHECK-LABEL: @test10(301; CHECK-NEXT: ret i32 0302;303 %tmp.1 = zext i8 %c to i32304 %tmp.2 = mul i32 %tmp.1, 4305 %tmp.3 = sext i32 %tmp.2 to i64306 %tmp.5 = urem i64 %tmp.3, 4307 %tmp.6 = trunc i64 %tmp.5 to i32308 ret i32 %tmp.6309}310 311define i32 @test11(i32 %i) {312; CHECK-LABEL: @test11(313; CHECK-NEXT: ret i32 0314;315 %tmp.1 = and i32 %i, -2316 %tmp.3 = mul i32 %tmp.1, 2317 %tmp.5 = urem i32 %tmp.3, 4318 ret i32 %tmp.5319}320 321define i32 @test12(i32 %i) {322; CHECK-LABEL: @test12(323; CHECK-NEXT: ret i32 0324;325 %tmp.1 = and i32 %i, -4326 %tmp.5 = srem i32 %tmp.1, 2327 ret i32 %tmp.5328}329 330define i32 @test13(i32 %i) {331; CHECK-LABEL: @test13(332; CHECK-NEXT: ret i32 0333;334 %x = srem i32 %i, %i335 ret i32 %x336}337 338define i64 @test14(i64 %x, i32 %y) {339; CHECK-LABEL: @test14(340; CHECK-NEXT: [[SHL:%.*]] = shl nuw i32 1, [[Y:%.*]]341; CHECK-NEXT: [[ZEXT:%.*]] = zext i32 [[SHL]] to i64342; CHECK-NEXT: [[TMP1:%.*]] = add nsw i64 [[ZEXT]], -1343; CHECK-NEXT: [[UREM:%.*]] = and i64 [[X:%.*]], [[TMP1]]344; CHECK-NEXT: ret i64 [[UREM]]345;346 %shl = shl i32 1, %y347 %zext = zext i32 %shl to i64348 %urem = urem i64 %x, %zext349 ret i64 %urem350}351 352define i64 @test15(i32 %x, i32 %y) {353; CHECK-LABEL: @test15(354; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i32 -1, [[Y:%.*]]355; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[NOTMASK]], -1356; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[X:%.*]], [[TMP1]]357; CHECK-NEXT: [[UREM:%.*]] = zext nneg i32 [[TMP2]] to i64358; CHECK-NEXT: ret i64 [[UREM]]359;360 %shl = shl i32 1, %y361 %zext0 = zext i32 %shl to i64362 %zext1 = zext i32 %x to i64363 %urem = urem i64 %zext1, %zext0364 ret i64 %urem365}366 367define i32 @test16(i32 %x, i32 %y) {368; CHECK-LABEL: @test16(369; CHECK-NEXT: [[SHR:%.*]] = lshr i32 [[Y:%.*]], 11370; CHECK-NEXT: [[AND:%.*]] = and i32 [[SHR]], 4371; CHECK-NEXT: [[TMP1:%.*]] = or disjoint i32 [[AND]], 3372; CHECK-NEXT: [[REM:%.*]] = and i32 [[X:%.*]], [[TMP1]]373; CHECK-NEXT: ret i32 [[REM]]374;375 %shr = lshr i32 %y, 11376 %and = and i32 %shr, 4377 %add = add i32 %and, 4378 %rem = urem i32 %x, %add379 ret i32 %rem380}381 382define i32 @test17(i32 %X) {383; CHECK-LABEL: @test17(384; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[X:%.*]], 1385; CHECK-NEXT: [[A:%.*]] = zext i1 [[TMP1]] to i32386; CHECK-NEXT: ret i32 [[A]]387;388 %A = urem i32 1, %X389 ret i32 %A390}391 392define i32 @test18(i16 %x, i32 %y) {393; CHECK-LABEL: @test18(394; CHECK-NEXT: [[TMP1:%.*]] = and i16 [[X:%.*]], 4395; CHECK-NEXT: [[DOTNOT:%.*]] = icmp eq i16 [[TMP1]], 0396; CHECK-NEXT: [[TMP2:%.*]] = select i1 [[DOTNOT]], i32 63, i32 31397; CHECK-NEXT: [[TMP3:%.*]] = and i32 [[Y:%.*]], [[TMP2]]398; CHECK-NEXT: ret i32 [[TMP3]]399;400 %1 = and i16 %x, 4401 %2 = icmp ne i16 %1, 0402 %3 = select i1 %2, i32 32, i32 64403 %4 = urem i32 %y, %3404 ret i32 %4405}406 407define i32 @test19(i32 %x, i32 %y) {408; CHECK-LABEL: @test19(409; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]410; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]411; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], [[B]]412; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A]]413; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1414; CHECK-NEXT: [[E:%.*]] = and i32 [[Y]], [[TMP1]]415; CHECK-NEXT: ret i32 [[E]]416;417 %A = shl i32 1, %x418 %B = shl i32 1, %y419 %C = and i32 %A, %B420 %D = add i32 %C, %A421 %E = urem i32 %y, %D422 ret i32 %E423}424 425define i32 @test19_commutative0(i32 %x, i32 %y) {426; CHECK-LABEL: @test19_commutative0(427; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]428; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]429; CHECK-NEXT: [[C:%.*]] = and i32 [[B]], [[A]]430; CHECK-NEXT: [[D:%.*]] = add i32 [[C]], [[A]]431; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1432; CHECK-NEXT: [[E:%.*]] = and i32 [[Y]], [[TMP1]]433; CHECK-NEXT: ret i32 [[E]]434;435 %A = shl i32 1, %x436 %B = shl i32 1, %y437 %C = and i32 %B, %A ; swapped438 %D = add i32 %C, %A439 %E = urem i32 %y, %D440 ret i32 %E441}442 443define i32 @test19_commutative1(i32 %x, i32 %y) {444; CHECK-LABEL: @test19_commutative1(445; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]446; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]447; CHECK-NEXT: [[C:%.*]] = and i32 [[A]], [[B]]448; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]]449; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1450; CHECK-NEXT: [[E:%.*]] = and i32 [[Y]], [[TMP1]]451; CHECK-NEXT: ret i32 [[E]]452;453 %A = shl i32 1, %x454 %B = shl i32 1, %y455 %C = and i32 %A, %B456 %D = add i32 %A, %C ; swapped457 %E = urem i32 %y, %D458 ret i32 %E459}460 461define i32 @test19_commutative2(i32 %x, i32 %y) {462; CHECK-LABEL: @test19_commutative2(463; CHECK-NEXT: [[A:%.*]] = shl nuw i32 1, [[X:%.*]]464; CHECK-NEXT: [[B:%.*]] = shl nuw i32 1, [[Y:%.*]]465; CHECK-NEXT: [[C:%.*]] = and i32 [[B]], [[A]]466; CHECK-NEXT: [[D:%.*]] = add i32 [[A]], [[C]]467; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[D]], -1468; CHECK-NEXT: [[E:%.*]] = and i32 [[Y]], [[TMP1]]469; CHECK-NEXT: ret i32 [[E]]470;471 %A = shl i32 1, %x472 %B = shl i32 1, %y473 %C = and i32 %B, %A ; swapped474 %D = add i32 %A, %C ; swapped475 %E = urem i32 %y, %D476 ret i32 %E477}478 479define <2 x i64> @test20(<2 x i64> %X, <2 x i1> %C) {480; CHECK-LABEL: @test20(481; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[C:%.*]], <2 x i64> <i64 1, i64 2>, <2 x i64> zeroinitializer482; CHECK-NEXT: ret <2 x i64> [[R]]483;484 %V = select <2 x i1> %C, <2 x i64> <i64 1, i64 2>, <2 x i64> <i64 8, i64 9>485 %R = urem <2 x i64> %V, <i64 2, i64 3>486 ret <2 x i64> %R487}488 489define i32 @test21(i1 %c0, ptr %p) {490; CHECK-LABEL: @test21(491; CHECK-NEXT: entry:492; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]493; CHECK: if.then:494; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4495; CHECK-NEXT: [[TMP0:%.*]] = srem i32 [[V]], 5496; CHECK-NEXT: br label [[IF_END]]497; CHECK: if.end:498; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ 0, [[ENTRY:%.*]] ]499; CHECK-NEXT: ret i32 [[LHS]]500;501entry:502 br i1 %c0, label %if.then, label %if.end503 504if.then:505 %v = load volatile i32, ptr %p506 br label %if.end507 508if.end:509 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]510 %rem = srem i32 %lhs, 5511 ret i32 %rem512}513 514@a = common global [5 x i16] zeroinitializer, align 2515@b = common global i16 0, align 2516 517define i32 @pr27968_0(i1 %c0, ptr %p) {518; CHECK-LABEL: @pr27968_0(519; CHECK-NEXT: entry:520; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]521; CHECK: if.then:522; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4523; CHECK-NEXT: br label [[IF_END]]524; CHECK: if.end:525; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @a, i64 8), @b526; CHECK-NEXT: br i1 [[CMP]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]527; CHECK: rem.is.safe:528; CHECK-NEXT: ret i32 0529; CHECK: rem.is.unsafe:530; CHECK-NEXT: ret i32 0531;532entry:533 br i1 %c0, label %if.then, label %if.end534 535if.then:536 %v = load volatile i32, ptr %p537 br label %if.end538 539if.end:540 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]541 %cmp = icmp eq ptr getelementptr inbounds ([5 x i16], ptr @a, i64 0, i64 4), @b542 br i1 %cmp, label %rem.is.safe, label %rem.is.unsafe543 544rem.is.safe:545 %ext = zext i1 %cmp to i32546 %rem = srem i32 %lhs, %ext547 ret i32 %rem548 549rem.is.unsafe:550 ret i32 0551}552 553define i32 @pr27968_1(i1 %c0, i1 %always_false, ptr %p) {554; CHECK-LABEL: @pr27968_1(555; CHECK-NEXT: entry:556; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]557; CHECK: if.then:558; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4559; CHECK-NEXT: br label [[IF_END]]560; CHECK: if.end:561; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[V]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ]562; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]563; CHECK: rem.is.safe:564; CHECK-NEXT: [[REM:%.*]] = srem i32 [[LHS]], -2147483648565; CHECK-NEXT: ret i32 [[REM]]566; CHECK: rem.is.unsafe:567; CHECK-NEXT: ret i32 0568;569entry:570 br i1 %c0, label %if.then, label %if.end571 572if.then:573 %v = load volatile i32, ptr %p574 br label %if.end575 576if.end:577 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]578 br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe579 580rem.is.safe:581 %rem = srem i32 %lhs, -2147483648582 ret i32 %rem583 584rem.is.unsafe:585 ret i32 0586}587 588define i32 @pr27968_2(i1 %c0, ptr %p) {589; CHECK-LABEL: @pr27968_2(590; CHECK-NEXT: entry:591; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]592; CHECK: if.then:593; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4594; CHECK-NEXT: br label [[IF_END]]595; CHECK: if.end:596; CHECK-NEXT: [[CMP:%.*]] = icmp eq ptr getelementptr inbounds nuw (i8, ptr @a, i64 8), @b597; CHECK-NEXT: br i1 [[CMP]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]598; CHECK: rem.is.safe:599; CHECK-NEXT: ret i32 0600; CHECK: rem.is.unsafe:601; CHECK-NEXT: ret i32 0602;603entry:604 br i1 %c0, label %if.then, label %if.end605 606if.then:607 %v = load volatile i32, ptr %p608 br label %if.end609 610if.end:611 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]612 %cmp = icmp eq ptr getelementptr inbounds ([5 x i16], ptr @a, i64 0, i64 4), @b613 br i1 %cmp, label %rem.is.safe, label %rem.is.unsafe614 615rem.is.safe:616 %ext = zext i1 %cmp to i32617 %rem = urem i32 %lhs, %ext618 ret i32 %rem619 620rem.is.unsafe:621 ret i32 0622}623 624define i32 @pr27968_3(i1 %c0, i1 %always_false, ptr %p) {625; CHECK-LABEL: @pr27968_3(626; CHECK-NEXT: entry:627; CHECK-NEXT: br i1 [[C0:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]628; CHECK: if.then:629; CHECK-NEXT: [[V:%.*]] = load volatile i32, ptr [[P:%.*]], align 4630; CHECK-NEXT: [[TMP0:%.*]] = and i32 [[V]], 2147483647631; CHECK-NEXT: br label [[IF_END]]632; CHECK: if.end:633; CHECK-NEXT: [[LHS:%.*]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ 5, [[ENTRY:%.*]] ]634; CHECK-NEXT: br i1 [[ALWAYS_FALSE:%.*]], label [[REM_IS_SAFE:%.*]], label [[REM_IS_UNSAFE:%.*]]635; CHECK: rem.is.safe:636; CHECK-NEXT: ret i32 [[LHS]]637; CHECK: rem.is.unsafe:638; CHECK-NEXT: ret i32 0639;640entry:641 br i1 %c0, label %if.then, label %if.end642 643if.then:644 %v = load volatile i32, ptr %p645 br label %if.end646 647if.end:648 %lhs = phi i32 [ %v, %if.then ], [ 5, %entry ]649 br i1 %always_false, label %rem.is.safe, label %rem.is.unsafe650 651rem.is.safe:652 %rem = urem i32 %lhs, -2147483648653 ret i32 %rem654 655rem.is.unsafe:656 ret i32 0657}658 659define i32 @test22(i32 %A) {660; CHECK-LABEL: @test22(661; CHECK-NEXT: [[AND:%.*]] = and i32 [[A:%.*]], 2147483647662; CHECK-NEXT: [[MUL:%.*]] = urem i32 [[AND]], 2147483647663; CHECK-NEXT: ret i32 [[MUL]]664;665 %and = and i32 %A, 2147483647666 %mul = srem i32 %and, 2147483647667 ret i32 %mul668}669 670define <2 x i32> @test23(<2 x i32> %A) {671; CHECK-LABEL: @test23(672; CHECK-NEXT: [[AND:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)673; CHECK-NEXT: [[MUL:%.*]] = urem <2 x i32> [[AND]], splat (i32 2147483647)674; CHECK-NEXT: ret <2 x i32> [[MUL]]675;676 %and = and <2 x i32> %A, <i32 2147483647, i32 2147483647>677 %mul = srem <2 x i32> %and, <i32 2147483647, i32 2147483647>678 ret <2 x i32> %mul679}680 681define i1 @test24(i32 %A) {682; CHECK-LABEL: @test24(683; CHECK-NEXT: [[B:%.*]] = and i32 [[A:%.*]], 2147483647684; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[B]], 0685; CHECK-NEXT: ret i1 [[C]]686;687 %B = urem i32 %A, 2147483648 ; signbit688 %C = icmp ne i32 %B, 0689 ret i1 %C690}691 692define <2 x i1> @test24_vec(<2 x i32> %A) {693; CHECK-LABEL: @test24_vec(694; CHECK-NEXT: [[B:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)695; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[B]], zeroinitializer696; CHECK-NEXT: ret <2 x i1> [[C]]697;698 %B = urem <2 x i32> %A, <i32 2147483648, i32 2147483648>699 %C = icmp ne <2 x i32> %B, zeroinitializer700 ret <2 x i1> %C701}702 703define i1 @test25(i32 %A) {704; CHECK-LABEL: @test25(705; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 2147483647706; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[TMP1]], 0707; CHECK-NEXT: ret i1 [[C]]708;709 %B = srem i32 %A, 2147483648 ; signbit710 %C = icmp ne i32 %B, 0711 ret i1 %C712}713 714define <2 x i1> @test25_vec(<2 x i32> %A) {715; CHECK-LABEL: @test25_vec(716; CHECK-NEXT: [[TMP1:%.*]] = and <2 x i32> [[A:%.*]], splat (i32 2147483647)717; CHECK-NEXT: [[C:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer718; CHECK-NEXT: ret <2 x i1> [[C]]719;720 %B = srem <2 x i32> %A, <i32 2147483648, i32 2147483648>721 %C = icmp ne <2 x i32> %B, zeroinitializer722 ret <2 x i1> %C723}724 725define i1 @test26(i32 %A, i32 %B) {726; CHECK-LABEL: @test26(727; CHECK-NEXT: [[NOTMASK:%.*]] = shl nsw i32 -1, [[B:%.*]]728; CHECK-NEXT: [[TMP1:%.*]] = xor i32 [[NOTMASK]], -1729; CHECK-NEXT: [[TMP2:%.*]] = and i32 [[A:%.*]], [[TMP1]]730; CHECK-NEXT: [[E:%.*]] = icmp ne i32 [[TMP2]], 0731; CHECK-NEXT: ret i1 [[E]]732;733 %C = shl i32 1, %B ; not a constant734 %D = srem i32 %A, %C735 %E = icmp ne i32 %D, 0736 ret i1 %E737}738 739define i1 @test27(i32 %A, ptr %remdst) {740; CHECK-LABEL: @test27(741; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], -2147483648742; CHECK-NEXT: store i32 [[B]], ptr [[REMDST:%.*]], align 1743; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[B]], 0744; CHECK-NEXT: ret i1 [[C]]745;746 %B = srem i32 %A, 2147483648 ; signbit747 store i32 %B, ptr %remdst, align 1 ; extra use of rem748 %C = icmp ne i32 %B, 0749 ret i1 %C750}751 752define i1 @test28(i32 %A) {753; CHECK-LABEL: @test28(754; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], 2147483647755; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[TMP1]], 0756; CHECK-NEXT: ret i1 [[C]]757;758 %B = srem i32 %A, 2147483648 ; signbit759 %C = icmp eq i32 %B, 0 ; another equality predicate760 ret i1 %C761}762 763define i1 @positive_and_odd_eq(i32 %A) {764; CHECK-LABEL: @positive_and_odd_eq(765; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -2147483647766; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[TMP1]], 1767; CHECK-NEXT: ret i1 [[C]]768;769 %B = srem i32 %A, 2770 %C = icmp eq i32 %B, 1771 ret i1 %C772}773 774define i1 @negative_and_odd_eq(i32 %A) {775; CHECK-LABEL: @negative_and_odd_eq(776; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], 2777; CHECK-NEXT: [[C:%.*]] = icmp eq i32 [[B]], -1778; CHECK-NEXT: ret i1 [[C]]779;780 %B = srem i32 %A, 2781 %C = icmp eq i32 %B, -1782 ret i1 %C783}784 785define i1 @positive_and_odd_ne(i32 %A) {786; CHECK-LABEL: @positive_and_odd_ne(787; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[A:%.*]], -2147483647788; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[TMP1]], 1789; CHECK-NEXT: ret i1 [[C]]790;791 %B = srem i32 %A, 2792 %C = icmp ne i32 %B, 1793 ret i1 %C794}795 796define i1 @negative_and_odd_ne(i32 %A) {797; CHECK-LABEL: @negative_and_odd_ne(798; CHECK-NEXT: [[B:%.*]] = srem i32 [[A:%.*]], 2799; CHECK-NEXT: [[C:%.*]] = icmp ne i32 [[B]], -1800; CHECK-NEXT: ret i1 [[C]]801;802 %B = srem i32 %A, 2803 %C = icmp ne i32 %B, -1804 ret i1 %C805}806 807; FP division-by-zero is not UB.808 809define double @PR34870(i1 %cond, double %x, double %y) {810; CHECK-LABEL: @PR34870(811; CHECK-NEXT: [[SEL:%.*]] = select i1 [[COND:%.*]], double [[Y:%.*]], double 0.000000e+00812; CHECK-NEXT: [[FMOD:%.*]] = frem double [[X:%.*]], [[SEL]]813; CHECK-NEXT: ret double [[FMOD]]814;815 %sel = select i1 %cond, double %y, double 0.0816 %fmod = frem double %x, %sel817 ret double %fmod818}819 820define i32 @srem_constant_dividend_select_of_constants_divisor(i1 %b) {821; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor(822; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 6, i32 0823; CHECK-NEXT: ret i32 [[R]]824;825 %s = select i1 %b, i32 12, i32 -3826 %r = srem i32 42, %s827 ret i32 %r828}829 830define i32 @srem_constant_dividend_select_of_constants_divisor_use(i1 %b) {831; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_use(832; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3833; CHECK-NEXT: call void @use(i32 [[S]])834; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 6, i32 0835; CHECK-NEXT: ret i32 [[R]]836;837 %s = select i1 %b, i32 12, i32 -3838 call void @use(i32 %s)839 %r = srem i32 42, %s840 ret i32 %r841}842 843; Rem-by-0 is immediate UB, so select is simplified.844 845define i32 @srem_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {846; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_0_arm(847; CHECK-NEXT: ret i32 6848;849 %s = select i1 %b, i32 12, i32 0850 %r = srem i32 42, %s851 ret i32 %r852}853 854; negative test - not safe to speculate rem with variable divisor855 856define i32 @srem_constant_dividend_select_divisor1(i1 %b, i32 %x) {857; CHECK-LABEL: @srem_constant_dividend_select_divisor1(858; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3859; CHECK-NEXT: [[R:%.*]] = srem i32 42, [[S]]860; CHECK-NEXT: ret i32 [[R]]861;862 %s = select i1 %b, i32 %x, i32 -3863 %r = srem i32 42, %s864 ret i32 %r865}866 867; negative test - not safe to speculate rem with variable divisor868 869define i32 @srem_constant_dividend_select_divisor2(i1 %b, i32 %x) {870; CHECK-LABEL: @srem_constant_dividend_select_divisor2(871; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]872; CHECK-NEXT: [[R:%.*]] = srem i32 42, [[S]]873; CHECK-NEXT: ret i32 [[R]]874;875 %s = select i1 %b, i32 12, i32 %x876 %r = srem i32 42, %s877 ret i32 %r878}879 880define <2 x i8> @srem_constant_dividend_select_of_constants_divisor_vec(i1 %b) {881; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_vec(882; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -2>, <2 x i8> <i8 2, i8 -2>883; CHECK-NEXT: ret <2 x i8> [[R]]884;885 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>886 %r = srem <2 x i8> <i8 42, i8 -42>, %s887 ret <2 x i8> %r888}889 890; Rem-by-0 element is immediate UB, so select is simplified.891 892define <2 x i8> @srem_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {893; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_vec_ub1(894; CHECK-NEXT: ret <2 x i8> <i8 2, i8 -2>895;896 %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4>897 %r = srem <2 x i8> <i8 42, i8 -42>, %s898 ret <2 x i8> %r899}900 901; SMIN % -1 element is poison.902 903define <2 x i8> @srem_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {904; CHECK-LABEL: @srem_constant_dividend_select_of_constants_divisor_vec_ub2(905; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -3>, <2 x i8> <i8 2, i8 poison>906; CHECK-NEXT: ret <2 x i8> [[R]]907;908 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>909 %r = srem <2 x i8> <i8 42, i8 -128>, %s910 ret <2 x i8> %r911}912 913; negative test - must have constant dividend914 915define i32 @srem_select_of_constants_divisor(i1 %b, i32 %x) {916; CHECK-LABEL: @srem_select_of_constants_divisor(917; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3918; CHECK-NEXT: [[R:%.*]] = srem i32 [[X:%.*]], [[S]]919; CHECK-NEXT: ret i32 [[R]]920;921 %s = select i1 %b, i32 12, i32 -3922 %r = srem i32 %x, %s923 ret i32 %r924}925 926define i32 @urem_constant_dividend_select_of_constants_divisor(i1 %b) {927; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor(928; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], i32 6, i32 42929; CHECK-NEXT: ret i32 [[R]]930;931 %s = select i1 %b, i32 12, i32 -3932 %r = urem i32 42, %s933 ret i32 %r934}935 936define i32 @urem_constant_dividend_select_of_constants_divisor_use(i1 %b) {937; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_use(938; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -3939; CHECK-NEXT: call void @use(i32 [[S]])940; CHECK-NEXT: [[R:%.*]] = select i1 [[B]], i32 6, i32 42941; CHECK-NEXT: ret i32 [[R]]942;943 %s = select i1 %b, i32 12, i32 -3944 call void @use(i32 %s)945 %r = urem i32 42, %s946 ret i32 %r947}948 949; Rem-by-0 is immediate UB, so select is simplified.950 951define i32 @urem_constant_dividend_select_of_constants_divisor_0_arm(i1 %b) {952; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_0_arm(953; CHECK-NEXT: ret i32 6954;955 %s = select i1 %b, i32 12, i32 0956 %r = urem i32 42, %s957 ret i32 %r958}959 960; negative test - not safe to speculate rem with variable divisor961 962define i32 @urem_constant_dividend_select_divisor1(i1 %b, i32 %x) {963; CHECK-LABEL: @urem_constant_dividend_select_divisor1(964; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 [[X:%.*]], i32 -3965; CHECK-NEXT: [[R:%.*]] = urem i32 42, [[S]]966; CHECK-NEXT: ret i32 [[R]]967;968 %s = select i1 %b, i32 %x, i32 -3969 %r = urem i32 42, %s970 ret i32 %r971}972 973; negative test - not safe to speculate rem with variable divisor974 975define i32 @urem_constant_dividend_select_divisor2(i1 %b, i32 %x) {976; CHECK-LABEL: @urem_constant_dividend_select_divisor2(977; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 [[X:%.*]]978; CHECK-NEXT: [[R:%.*]] = urem i32 42, [[S]]979; CHECK-NEXT: ret i32 [[R]]980;981 %s = select i1 %b, i32 12, i32 %x982 %r = urem i32 42, %s983 ret i32 %r984}985 986define <2 x i8> @urem_constant_dividend_select_of_constants_divisor_vec(i1 %b) {987; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_vec(988; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -42>, <2 x i8> <i8 42, i8 2>989; CHECK-NEXT: ret <2 x i8> [[R]]990;991 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 4>992 %r = urem <2 x i8> <i8 42, i8 -42>, %s993 ret <2 x i8> %r994}995 996; Rem-by-0 element is immediate UB, so select is simplified.997 998define <2 x i8> @urem_constant_dividend_select_of_constants_divisor_vec_ub1(i1 %b) {999; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_vec_ub1(1000; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 poison, i8 -42>, <2 x i8> <i8 42, i8 2>1001; CHECK-NEXT: ret <2 x i8> [[R]]1002;1003 %s = select i1 %b, <2 x i8> <i8 0, i8 -5>, <2 x i8> <i8 -4, i8 4>1004 %r = urem <2 x i8> <i8 42, i8 -42>, %s1005 ret <2 x i8> %r1006}1007 1008; There's no unsigned equivalent to "SMIN % -1", so this is just the usual constant folding.1009 1010define <2 x i8> @urem_constant_dividend_select_of_constants_divisor_vec_ub2(i1 %b) {1011; CHECK-LABEL: @urem_constant_dividend_select_of_constants_divisor_vec_ub2(1012; CHECK-NEXT: [[R:%.*]] = select i1 [[B:%.*]], <2 x i8> <i8 6, i8 -128>, <2 x i8> <i8 42, i8 -128>1013; CHECK-NEXT: ret <2 x i8> [[R]]1014;1015 %s = select i1 %b, <2 x i8> <i8 12, i8 -5>, <2 x i8> <i8 -4, i8 -1>1016 %r = urem <2 x i8> <i8 42, i8 -128>, %s1017 ret <2 x i8> %r1018}1019 1020; negative test - must have constant dividend1021 1022define i32 @urem_select_of_constants_divisor(i1 %b, i32 %x) {1023; CHECK-LABEL: @urem_select_of_constants_divisor(1024; CHECK-NEXT: [[S:%.*]] = select i1 [[B:%.*]], i32 12, i32 -31025; CHECK-NEXT: [[R:%.*]] = urem i32 [[X:%.*]], [[S]]1026; CHECK-NEXT: ret i32 [[R]]1027;1028 %s = select i1 %b, i32 12, i32 -31029 %r = urem i32 %x, %s1030 ret i32 %r1031}1032 1033; https://alive2.llvm.org/ce/z/bh2KHm1034define <2 x i32> @PR62401(<2 x i1> %x, <2 x i32> %y) {1035; CHECK-LABEL: @PR62401(1036; CHECK-NEXT: [[Y_FROZEN:%.*]] = freeze <2 x i32> [[Y:%.*]]1037; CHECK-NEXT: [[TMP1:%.*]] = icmp eq <2 x i32> [[Y_FROZEN]], splat (i32 -1)1038; CHECK-NEXT: [[R:%.*]] = select <2 x i1> [[TMP1]], <2 x i32> zeroinitializer, <2 x i32> [[Y_FROZEN]]1039; CHECK-NEXT: ret <2 x i32> [[R]]1040;1041 %sext.i1 = sext <2 x i1> %x to <2 x i32>1042 %r = urem <2 x i32> %y, %sext.i11043 ret <2 x i32> %r1044}1045 1046define i16 @rem_pow2_or_zero(i16 %x, i16 %y) {1047; CHECK-LABEL: @rem_pow2_or_zero(1048; CHECK-NEXT: [[POPCNT:%.*]] = call range(i16 1, 17) i16 @llvm.ctpop.i16(i16 [[Y:%.*]])1049; CHECK-NEXT: [[COND:%.*]] = icmp samesign ult i16 [[POPCNT]], 21050; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]])1051; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[Y]], -11052; CHECK-NEXT: [[REM:%.*]] = and i16 [[X:%.*]], [[TMP1]]1053; CHECK-NEXT: ret i16 [[REM]]1054;1055 %popcnt = call i16 @llvm.ctpop.i16(i16 %y)1056 %cond = icmp ult i16 %popcnt, 21057 tail call void @llvm.assume(i1 %cond)1058 %rem = urem i16 %x, %y1059 ret i16 %rem1060}1061 1062define i16 @rem_pow2(i16 %x, i16 %y) {1063; CHECK-LABEL: @rem_pow2(1064; CHECK-NEXT: [[POPCNT:%.*]] = call range(i16 1, 17) i16 @llvm.ctpop.i16(i16 [[Y:%.*]])1065; CHECK-NEXT: [[COND:%.*]] = icmp eq i16 [[POPCNT]], 11066; CHECK-NEXT: tail call void @llvm.assume(i1 [[COND]])1067; CHECK-NEXT: [[TMP1:%.*]] = add i16 [[Y]], -11068; CHECK-NEXT: [[REM:%.*]] = and i16 [[X:%.*]], [[TMP1]]1069; CHECK-NEXT: ret i16 [[REM]]1070;1071 %popcnt = call i16 @llvm.ctpop.i16(i16 %y)1072 %cond = icmp eq i16 %popcnt, 11073 tail call void @llvm.assume(i1 %cond)1074 %rem = urem i16 %x, %y1075 ret i16 %rem1076}1077 1078define i64 @rem_pow2_domcond(i64 %a, i64 %b) {1079; CHECK-LABEL: @rem_pow2_domcond(1080; CHECK-NEXT: start:1081; CHECK-NEXT: [[CPOP:%.*]] = call range(i64 0, 65) i64 @llvm.ctpop.i64(i64 [[B:%.*]])1082; CHECK-NEXT: [[COND:%.*]] = icmp eq i64 [[CPOP]], 11083; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]1084; CHECK: bb1:1085; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[B]], -11086; CHECK-NEXT: [[REM:%.*]] = and i64 [[A:%.*]], [[TMP0]]1087; CHECK-NEXT: ret i64 [[REM]]1088; CHECK: bb2:1089; CHECK-NEXT: ret i64 01090;1091start:1092 %cpop = call i64 @llvm.ctpop.i64(i64 %b)1093 %cond = icmp eq i64 %cpop, 11094 br i1 %cond, label %bb1, label %bb21095 1096bb1:1097 %rem = urem i64 %a, %b1098 ret i64 %rem1099 1100bb2:1101 ret i64 01102}1103 1104define i64 @rem_pow2_domcond_in_else(i64 %a, i64 %b) {1105; CHECK-LABEL: @rem_pow2_domcond_in_else(1106; CHECK-NEXT: start:1107; CHECK-NEXT: [[CPOP:%.*]] = call range(i64 0, 65) i64 @llvm.ctpop.i64(i64 [[B:%.*]])1108; CHECK-NEXT: [[COND_NOT:%.*]] = icmp eq i64 [[CPOP]], 11109; CHECK-NEXT: br i1 [[COND_NOT]], label [[BB1:%.*]], label [[BB2:%.*]]1110; CHECK: bb1:1111; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[B]], -11112; CHECK-NEXT: [[REM:%.*]] = and i64 [[A:%.*]], [[TMP0]]1113; CHECK-NEXT: ret i64 [[REM]]1114; CHECK: bb2:1115; CHECK-NEXT: ret i64 01116;1117start:1118 %cpop = call i64 @llvm.ctpop.i64(i64 %b)1119 %cond = icmp ne i64 %cpop, 11120 br i1 %cond, label %bb2, label %bb11121 1122bb1:1123 %rem = urem i64 %a, %b1124 ret i64 %rem1125 1126bb2:1127 ret i64 01128}1129 1130define i64 @rem_pow2_or_zero_domcond(i64 %a, i64 %b) {1131; CHECK-LABEL: @rem_pow2_or_zero_domcond(1132; CHECK-NEXT: start:1133; CHECK-NEXT: [[CPOP:%.*]] = call range(i64 0, 65) i64 @llvm.ctpop.i64(i64 [[B:%.*]])1134; CHECK-NEXT: [[COND:%.*]] = icmp samesign ult i64 [[CPOP]], 21135; CHECK-NEXT: br i1 [[COND]], label [[BB1:%.*]], label [[BB2:%.*]]1136; CHECK: bb1:1137; CHECK-NEXT: [[TMP0:%.*]] = add i64 [[B]], -11138; CHECK-NEXT: [[REM:%.*]] = and i64 [[A:%.*]], [[TMP0]]1139; CHECK-NEXT: ret i64 [[REM]]1140; CHECK: bb2:1141; CHECK-NEXT: ret i64 01142;1143start:1144 %cpop = call i64 @llvm.ctpop.i64(i64 %b)1145 %cond = icmp ult i64 %cpop, 21146 br i1 %cond, label %bb1, label %bb21147 1148bb1:1149 %rem = urem i64 %a, %b1150 ret i64 %rem1151 1152bb2:1153 ret i64 01154}1155 1156define i64 @rem_pow2_non_domcond(i64 %a, i64 %b) {1157; CHECK-LABEL: @rem_pow2_non_domcond(1158; CHECK-NEXT: start:1159; CHECK-NEXT: [[CPOP:%.*]] = call range(i64 0, 65) i64 @llvm.ctpop.i64(i64 [[B:%.*]])1160; CHECK-NEXT: [[COND_NOT:%.*]] = icmp eq i64 [[CPOP]], 11161; CHECK-NEXT: br i1 [[COND_NOT]], label [[BB1:%.*]], label [[BB2:%.*]]1162; CHECK: bb1:1163; CHECK-NEXT: [[REM:%.*]] = urem i64 [[A:%.*]], [[B]]1164; CHECK-NEXT: ret i64 [[REM]]1165; CHECK: bb2:1166; CHECK-NEXT: br label [[BB1]]1167;1168start:1169 %cpop = call i64 @llvm.ctpop.i64(i64 %b)1170 %cond = icmp ne i64 %cpop, 11171 br i1 %cond, label %bb2, label %bb11172 1173bb1:1174 %rem = urem i64 %a, %b1175 ret i64 %rem1176 1177bb2:1178 br label %bb11179}1180