brintos

brintos / llvm-project-archived public Read only

0
0
Text · 34.1 KiB · 198a706 Raw
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