brintos

brintos / llvm-project-archived public Read only

0
0
Text · 20.4 KiB · 7cfb6af Raw
645 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 22; RUN: opt -S -passes=instcombine < %s | FileCheck %s3 4; https://llvm.org/bugs/show_bug.cgi?id=259005; An arithmetic shift right of a power of two is not a power6; of two if the original value is the sign bit. Therefore,7; we can't transform the sdiv into a udiv.8 9declare i16 @llvm.bitreverse.i16(i16)10declare i16 @llvm.bswap.i16(i16)11declare i16 @llvm.ctpop.i16(i16)12declare i16 @llvm.fshl.i16(i16, i16, i16)13declare i16 @llvm.fshr.i16(i16, i16, i16)14declare i16 @llvm.umax.i16(i16, i16)15 16define i32 @pr25900(i32 %d) {17; CHECK-LABEL: define i32 @pr2590018; CHECK-SAME: (i32 [[D:%.*]]) {19; CHECK-NEXT:    [[ASHR:%.*]] = ashr i32 [[D]], 3120; CHECK-NEXT:    [[DIV:%.*]] = sdiv i32 4, [[ASHR]]21; CHECK-NEXT:    ret i32 [[DIV]]22;23  %and = and i32 %d, -214748364824; The next 3 lines prevent another fold from masking the bug.25  %ext = zext i32 %and to i6426  %or = or i64 %ext, 429496729627  %trunc = trunc i64 %or to i3228  %ashr = ashr exact i32 %trunc, 3129  %div = sdiv i32 4, %ashr30  ret i32 %div31 32}33 34define i8 @trunc_is_pow2_or_zero(i16 %x, i8 %y) {35; CHECK-LABEL: define i8 @trunc_is_pow2_or_zero36; CHECK-SAME: (i16 [[X:%.*]], i8 [[Y:%.*]]) {37; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]38; CHECK-NEXT:    [[XX:%.*]] = trunc i16 [[XP2]] to i839; CHECK-NEXT:    [[TMP1:%.*]] = add i8 [[XX]], -140; CHECK-NEXT:    [[R:%.*]] = and i8 [[Y]], [[TMP1]]41; CHECK-NEXT:    ret i8 [[R]]42;43  %xp2 = shl i16 4, %x44  %xx = trunc i16 %xp2 to i845 46  %r = urem i8 %y, %xx47  ret i8 %r48}49 50define i8 @trunc_is_pow2_or_zero_fail(i16 %x, i8 %y) {51; CHECK-LABEL: define i8 @trunc_is_pow2_or_zero_fail52; CHECK-SAME: (i16 [[X:%.*]], i8 [[Y:%.*]]) {53; CHECK-NEXT:    [[XP2:%.*]] = shl i16 5, [[X]]54; CHECK-NEXT:    [[XX:%.*]] = trunc i16 [[XP2]] to i855; CHECK-NEXT:    [[R:%.*]] = urem i8 [[Y]], [[XX]]56; CHECK-NEXT:    ret i8 [[R]]57;58  %xp2 = shl i16 5, %x59  %xx = trunc i16 %xp2 to i860 61  %r = urem i8 %y, %xx62  ret i8 %r63}64 65define i1 @trunc_is_pow2_fail(i16 %x, i8 %y) {66; CHECK-LABEL: define i1 @trunc_is_pow2_fail67; CHECK-SAME: (i16 [[X:%.*]], i8 [[Y:%.*]]) {68; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]69; CHECK-NEXT:    [[XX:%.*]] = trunc i16 [[XP2]] to i870; CHECK-NEXT:    [[AND:%.*]] = and i8 [[Y]], [[XX]]71; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[AND]], [[XX]]72; CHECK-NEXT:    ret i1 [[R]]73;74  %xp2 = shl i16 4, %x75  %xx = trunc i16 %xp2 to i876 77  %and = and i8 %y, %xx78  %r = icmp eq i8 %and, %xx79  ret i1 %r80}81 82define i16 @bswap_is_pow2_or_zero(i16 %x, i16 %y) {83; CHECK-LABEL: define i16 @bswap_is_pow2_or_zero84; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {85; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]86; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bswap.i16(i16 [[XP2]])87; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[XX]], -188; CHECK-NEXT:    [[R:%.*]] = and i16 [[Y]], [[TMP1]]89; CHECK-NEXT:    ret i16 [[R]]90;91  %xp2 = shl i16 4, %x92  %xx = call i16 @llvm.bswap.i16(i16 %xp2)93 94  %r = urem i16 %y, %xx95  ret i16 %r96}97 98define i16 @bswap_is_pow2_or_zero_fail(i16 %x, i16 %y) {99; CHECK-LABEL: define i16 @bswap_is_pow2_or_zero_fail100; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {101; CHECK-NEXT:    [[XP2:%.*]] = shl i16 5, [[X]]102; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bswap.i16(i16 [[XP2]])103; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]104; CHECK-NEXT:    ret i16 [[R]]105;106  %xp2 = shl i16 5, %x107  %xx = call i16 @llvm.bswap.i16(i16 %xp2)108 109  %r = urem i16 %y, %xx110  ret i16 %r111}112 113define i1 @bswap_is_pow2(i16 %x, i16 %y) {114; CHECK-LABEL: define i1 @bswap_is_pow2115; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {116; CHECK-NEXT:    [[XP2:%.*]] = shl nuw i16 1, [[X]]117; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bswap.i16(i16 [[XP2]])118; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]119; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0120; CHECK-NEXT:    ret i1 [[R]]121;122  %xp2 = shl i16 1, %x123  %xx = call i16 @llvm.bswap.i16(i16 %xp2)124 125  %and = and i16 %y, %xx126  %r = icmp eq i16 %and, %xx127  ret i1 %r128}129 130define i1 @bswap_is_pow2_fail(i16 %x, i16 %y) {131; CHECK-LABEL: define i1 @bswap_is_pow2_fail132; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {133; CHECK-NEXT:    [[XP2:%.*]] = shl i16 2, [[X]]134; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bswap.i16(i16 [[XP2]])135; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]136; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]137; CHECK-NEXT:    ret i1 [[R]]138;139  %xp2 = shl i16 2, %x140  %xx = call i16 @llvm.bswap.i16(i16 %xp2)141 142  %and = and i16 %y, %xx143  %r = icmp eq i16 %and, %xx144  ret i1 %r145}146 147define i16 @bitreverse_is_pow2_or_zero(i16 %x, i16 %y) {148; CHECK-LABEL: define i16 @bitreverse_is_pow2_or_zero149; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {150; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]151; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[XP2]])152; CHECK-NEXT:    [[TMP1:%.*]] = add nsw i16 [[XX]], -1153; CHECK-NEXT:    [[R:%.*]] = and i16 [[Y]], [[TMP1]]154; CHECK-NEXT:    ret i16 [[R]]155;156  %xp2 = shl i16 4, %x157  %xx = call i16 @llvm.bitreverse.i16(i16 %xp2)158 159  %r = urem i16 %y, %xx160  ret i16 %r161}162 163define i16 @bitreverse_is_pow2_or_zero_fail(i16 %x, i16 %y) {164; CHECK-LABEL: define i16 @bitreverse_is_pow2_or_zero_fail165; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {166; CHECK-NEXT:    [[XP2:%.*]] = shl i16 5, [[X]]167; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[XP2]])168; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]169; CHECK-NEXT:    ret i16 [[R]]170;171  %xp2 = shl i16 5, %x172  %xx = call i16 @llvm.bitreverse.i16(i16 %xp2)173 174  %r = urem i16 %y, %xx175  ret i16 %r176}177 178define i1 @bitreverse_is_pow2(i16 %x, i16 %y) {179; CHECK-LABEL: define i1 @bitreverse_is_pow2180; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {181; CHECK-NEXT:    [[XP2:%.*]] = shl nuw i16 1, [[X]]182; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[XP2]])183; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]184; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0185; CHECK-NEXT:    ret i1 [[R]]186;187  %xp2 = shl i16 1, %x188  %xx = call i16 @llvm.bitreverse.i16(i16 %xp2)189 190  %and = and i16 %y, %xx191  %r = icmp eq i16 %and, %xx192  ret i1 %r193}194 195define i1 @bitreverse_is_pow2_fail(i16 %x, i16 %y) {196; CHECK-LABEL: define i1 @bitreverse_is_pow2_fail197; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {198; CHECK-NEXT:    [[XP2:%.*]] = shl i16 2, [[X]]199; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.bitreverse.i16(i16 [[XP2]])200; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]201; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]202; CHECK-NEXT:    ret i1 [[R]]203;204  %xp2 = shl i16 2, %x205  %xx = call i16 @llvm.bitreverse.i16(i16 %xp2)206 207  %and = and i16 %y, %xx208  %r = icmp eq i16 %and, %xx209  ret i1 %r210}211 212define i16 @fshl_is_pow2_or_zero(i16 %x, i16 %y, i16 %z) {213; CHECK-LABEL: define i16 @fshl_is_pow2_or_zero214; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {215; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]216; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])217; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[XX]], -1218; CHECK-NEXT:    [[R:%.*]] = and i16 [[Y]], [[TMP1]]219; CHECK-NEXT:    ret i16 [[R]]220;221  %xp2 = shl i16 4, %x222  %xx = call i16 @llvm.fshl.i16(i16 %xp2, i16 %xp2, i16 %z)223 224  %r = urem i16 %y, %xx225  ret i16 %r226}227 228define i16 @fshl_is_pow2_or_zero_fail_not_rotate(i16 %w, i16 %x, i16 %y, i16 %z) {229; CHECK-LABEL: define i16 @fshl_is_pow2_or_zero_fail_not_rotate230; CHECK-SAME: (i16 [[W:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {231; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]232; CHECK-NEXT:    [[WP2:%.*]] = shl i16 2, [[W]]233; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XP2]], i16 [[WP2]], i16 [[Z]])234; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]235; CHECK-NEXT:    ret i16 [[R]]236;237  %xp2 = shl i16 4, %x238  %wp2 = shl i16 2, %w239  %xx = call i16 @llvm.fshl.i16(i16 %xp2, i16 %wp2, i16 %z)240 241  %r = urem i16 %y, %xx242  ret i16 %r243}244 245define i16 @fshl_is_pow2_or_zero_fail(i16 %x, i16 %y, i16 %z) {246; CHECK-LABEL: define i16 @fshl_is_pow2_or_zero_fail247; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {248; CHECK-NEXT:    [[XP2:%.*]] = shl i16 5, [[X]]249; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])250; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]251; CHECK-NEXT:    ret i16 [[R]]252;253  %xp2 = shl i16 5, %x254  %xx = call i16 @llvm.fshl.i16(i16 %xp2, i16 %xp2, i16 %z)255 256  %r = urem i16 %y, %xx257  ret i16 %r258}259 260define i1 @fshl_is_pow2(i16 %x, i16 %y, i16 %z) {261; CHECK-LABEL: define i1 @fshl_is_pow2262; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {263; CHECK-NEXT:    [[XP2:%.*]] = shl nuw i16 1, [[X]]264; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])265; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]266; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0267; CHECK-NEXT:    ret i1 [[R]]268;269  %xp2 = shl i16 1, %x270  %xx = call i16 @llvm.fshl.i16(i16 %xp2, i16 %xp2, i16 %z)271 272  %and = and i16 %y, %xx273  %r = icmp eq i16 %and, %xx274  ret i1 %r275}276 277define i1 @fshl_is_pow2_fail(i16 %x, i16 %y, i16 %z) {278; CHECK-LABEL: define i1 @fshl_is_pow2_fail279; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {280; CHECK-NEXT:    [[XP2:%.*]] = shl i16 2, [[X]]281; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshl.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])282; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]283; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]284; CHECK-NEXT:    ret i1 [[R]]285;286  %xp2 = shl i16 2, %x287  %xx = call i16 @llvm.fshl.i16(i16 %xp2, i16 %xp2, i16 %z)288 289  %and = and i16 %y, %xx290  %r = icmp eq i16 %and, %xx291  ret i1 %r292}293 294define i16 @fshr_is_pow2_or_zero(i16 %x, i16 %y, i16 %z) {295; CHECK-LABEL: define i16 @fshr_is_pow2_or_zero296; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {297; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]298; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshr.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])299; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[XX]], -1300; CHECK-NEXT:    [[R:%.*]] = and i16 [[Y]], [[TMP1]]301; CHECK-NEXT:    ret i16 [[R]]302;303  %xp2 = shl i16 4, %x304  %xx = call i16 @llvm.fshr.i16(i16 %xp2, i16 %xp2, i16 %z)305 306  %r = urem i16 %y, %xx307  ret i16 %r308}309 310define i16 @fshr_is_pow2_or_zero_fail_not_rotate(i16 %w, i16 %x, i16 %y, i16 %z) {311; CHECK-LABEL: define i16 @fshr_is_pow2_or_zero_fail_not_rotate312; CHECK-SAME: (i16 [[W:%.*]], i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {313; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]314; CHECK-NEXT:    [[WP2:%.*]] = shl i16 2, [[W]]315; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshr.i16(i16 [[XP2]], i16 [[WP2]], i16 [[Z]])316; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]317; CHECK-NEXT:    ret i16 [[R]]318;319  %xp2 = shl i16 4, %x320  %wp2 = shl i16 2, %w321  %xx = call i16 @llvm.fshr.i16(i16 %xp2, i16 %wp2, i16 %z)322 323  %r = urem i16 %y, %xx324  ret i16 %r325}326 327define i16 @fshr_is_pow2_or_zero_fail(i16 %x, i16 %y, i16 %z) {328; CHECK-LABEL: define i16 @fshr_is_pow2_or_zero_fail329; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {330; CHECK-NEXT:    [[XP2:%.*]] = shl i16 5, [[X]]331; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshr.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])332; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]333; CHECK-NEXT:    ret i16 [[R]]334;335  %xp2 = shl i16 5, %x336  %xx = call i16 @llvm.fshr.i16(i16 %xp2, i16 %xp2, i16 %z)337 338  %r = urem i16 %y, %xx339  ret i16 %r340}341 342define i1 @fshr_is_pow2(i16 %x, i16 %y, i16 %z) {343; CHECK-LABEL: define i1 @fshr_is_pow2344; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {345; CHECK-NEXT:    [[XP2:%.*]] = shl nuw i16 1, [[X]]346; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshr.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])347; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]348; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0349; CHECK-NEXT:    ret i1 [[R]]350;351  %xp2 = shl i16 1, %x352  %xx = call i16 @llvm.fshr.i16(i16 %xp2, i16 %xp2, i16 %z)353 354  %and = and i16 %y, %xx355  %r = icmp eq i16 %and, %xx356  ret i1 %r357}358 359define i1 @fshr_is_pow2_fail(i16 %x, i16 %y, i16 %z) {360; CHECK-LABEL: define i1 @fshr_is_pow2_fail361; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {362; CHECK-NEXT:    [[XP2:%.*]] = shl i16 2, [[X]]363; CHECK-NEXT:    [[XX:%.*]] = call i16 @llvm.fshr.i16(i16 [[XP2]], i16 [[XP2]], i16 [[Z]])364; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]365; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]366; CHECK-NEXT:    ret i1 [[R]]367;368  %xp2 = shl i16 2, %x369  %xx = call i16 @llvm.fshr.i16(i16 %xp2, i16 %xp2, i16 %z)370 371  %and = and i16 %y, %xx372  %r = icmp eq i16 %and, %xx373  ret i1 %r374}375 376define i16 @mul_is_pow2_or_zero(i16 %x, i16 %y, i16 %z) {377; CHECK-LABEL: define i16 @mul_is_pow2_or_zero378; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {379; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]380; CHECK-NEXT:    [[ZP2:%.*]] = shl i16 2, [[Z]]381; CHECK-NEXT:    [[XX:%.*]] = mul i16 [[XP2]], [[ZP2]]382; CHECK-NEXT:    [[TMP1:%.*]] = add i16 [[XX]], -1383; CHECK-NEXT:    [[R:%.*]] = and i16 [[Y]], [[TMP1]]384; CHECK-NEXT:    ret i16 [[R]]385;386  %xp2 = shl i16 4, %x387  %zp2 = shl i16 2, %z388  %xx = mul i16 %xp2, %zp2389 390  %r = urem i16 %y, %xx391  ret i16 %r392}393 394define i16 @mul_is_pow2_or_zero_fail(i16 %x, i16 %y, i16 %z) {395; CHECK-LABEL: define i16 @mul_is_pow2_or_zero_fail396; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {397; CHECK-NEXT:    [[XP2:%.*]] = shl i16 4, [[X]]398; CHECK-NEXT:    [[ZP2:%.*]] = shl i16 5, [[Z]]399; CHECK-NEXT:    [[XX:%.*]] = mul i16 [[XP2]], [[ZP2]]400; CHECK-NEXT:    [[R:%.*]] = urem i16 [[Y]], [[XX]]401; CHECK-NEXT:    ret i16 [[R]]402;403  %xp2 = shl i16 4, %x404  %zp2 = shl i16 5, %z405  %xx = mul i16 %xp2, %zp2406 407  %r = urem i16 %y, %xx408  ret i16 %r409}410 411define i1 @mul_is_pow2(i16 %x, i16 %y, i16 %z) {412; CHECK-LABEL: define i1 @mul_is_pow2413; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {414; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 3415; CHECK-NEXT:    [[ZSMALL:%.*]] = and i16 [[Z]], 3416; CHECK-NEXT:    [[ZP2:%.*]] = shl nuw nsw i16 2, [[ZSMALL]]417; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i16 [[XSMALL]], 2418; CHECK-NEXT:    [[XX:%.*]] = shl nuw nsw i16 [[ZP2]], [[TMP1]]419; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]420; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0421; CHECK-NEXT:    ret i1 [[R]]422;423  %xsmall = and i16 %x, 3424  %zsmall = and i16 %z, 3425  %xp2 = shl i16 4, %xsmall426  %zp2 = shl i16 2, %zsmall427  %xx = mul i16 %xp2, %zp2428 429  %and = and i16 %y, %xx430  %r = icmp eq i16 %and, %xx431  ret i1 %r432}433 434define i1 @mul_is_pow2_fail(i16 %x, i16 %y, i16 %z) {435; CHECK-LABEL: define i1 @mul_is_pow2_fail436; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {437; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7438; CHECK-NEXT:    [[ZSMALL:%.*]] = and i16 [[Z]], 7439; CHECK-NEXT:    [[ZP2:%.*]] = shl nuw nsw i16 2, [[ZSMALL]]440; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i16 [[XSMALL]], 2441; CHECK-NEXT:    [[XX:%.*]] = shl i16 [[ZP2]], [[TMP1]]442; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]443; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]444; CHECK-NEXT:    ret i1 [[R]]445;446  %xsmall = and i16 %x, 7447  %zsmall = and i16 %z, 7448  %xp2 = shl i16 4, %xsmall449  %zp2 = shl i16 2, %zsmall450  %xx = mul i16 %xp2, %zp2451 452  %and = and i16 %y, %xx453  %r = icmp eq i16 %and, %xx454  ret i1 %r455}456 457define i1 @mul_is_pow2_fail2(i16 %x, i16 %y, i16 %z) {458; CHECK-LABEL: define i1 @mul_is_pow2_fail2459; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]], i16 [[Z:%.*]]) {460; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 3461; CHECK-NEXT:    [[ZSMALL:%.*]] = and i16 [[Z]], 3462; CHECK-NEXT:    [[XP2:%.*]] = shl nuw nsw i16 3, [[XSMALL]]463; CHECK-NEXT:    [[TMP1:%.*]] = add nuw nsw i16 [[ZSMALL]], 1464; CHECK-NEXT:    [[XX:%.*]] = shl nuw nsw i16 [[XP2]], [[TMP1]]465; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]466; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]467; CHECK-NEXT:    ret i1 [[R]]468;469  %xsmall = and i16 %x, 3470  %zsmall = and i16 %z, 3471  %xp2 = shl i16 3, %xsmall472  %zp2 = shl i16 2, %zsmall473  %xx = mul i16 %xp2, %zp2474 475  %and = and i16 %y, %xx476  %r = icmp eq i16 %and, %xx477  ret i1 %r478}479 480define i1 @shl_is_pow2(i16 %x, i16 %y) {481; CHECK-LABEL: define i1 @shl_is_pow2482; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {483; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7484; CHECK-NEXT:    [[XX:%.*]] = shl nuw nsw i16 4, [[XSMALL]]485; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]486; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0487; CHECK-NEXT:    ret i1 [[R]]488;489  %xsmall = and i16 %x, 7490  %xx = shl i16 4, %xsmall491 492  %and = and i16 %y, %xx493  %r = icmp eq i16 %and, %xx494  ret i1 %r495}496 497define i1 @shl_is_pow2_fail(i16 %x, i16 %y) {498; CHECK-LABEL: define i1 @shl_is_pow2_fail499; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {500; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7501; CHECK-NEXT:    [[XX:%.*]] = shl i16 512, [[XSMALL]]502; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]503; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]504; CHECK-NEXT:    ret i1 [[R]]505;506  %xsmall = and i16 %x, 7507  %xx = shl i16 512, %xsmall508 509  %and = and i16 %y, %xx510  %r = icmp eq i16 %and, %xx511  ret i1 %r512}513 514define i1 @shl_is_pow2_fail2(i16 %x, i16 %y) {515; CHECK-LABEL: define i1 @shl_is_pow2_fail2516; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {517; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7518; CHECK-NEXT:    [[XX:%.*]] = shl nuw nsw i16 5, [[XSMALL]]519; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]520; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]521; CHECK-NEXT:    ret i1 [[R]]522;523  %xsmall = and i16 %x, 7524  %xx = shl i16 5, %xsmall525 526  %and = and i16 %y, %xx527  %r = icmp eq i16 %and, %xx528  ret i1 %r529}530 531define i1 @lshr_is_pow2(i16 %x, i16 %y) {532; CHECK-LABEL: define i1 @lshr_is_pow2533; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {534; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7535; CHECK-NEXT:    [[XX:%.*]] = lshr exact i16 512, [[XSMALL]]536; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]537; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0538; CHECK-NEXT:    ret i1 [[R]]539;540  %xsmall = and i16 %x, 7541  %xx = lshr i16 512, %xsmall542 543  %and = and i16 %y, %xx544  %r = icmp eq i16 %and, %xx545  ret i1 %r546}547 548define i1 @lshr_is_pow2_fail(i16 %x, i16 %y) {549; CHECK-LABEL: define i1 @lshr_is_pow2_fail550; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {551; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7552; CHECK-NEXT:    [[XX:%.*]] = lshr i16 4, [[XSMALL]]553; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]554; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]555; CHECK-NEXT:    ret i1 [[R]]556;557  %xsmall = and i16 %x, 7558  %xx = lshr i16 4, %xsmall559 560  %and = and i16 %y, %xx561  %r = icmp eq i16 %and, %xx562  ret i1 %r563}564 565define i1 @lshr_is_pow2_fail2(i16 %x, i16 %y) {566; CHECK-LABEL: define i1 @lshr_is_pow2_fail2567; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {568; CHECK-NEXT:    [[XSMALL:%.*]] = and i16 [[X]], 7569; CHECK-NEXT:    [[XX:%.*]] = lshr i16 513, [[XSMALL]]570; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]571; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]572; CHECK-NEXT:    ret i1 [[R]]573;574  %xsmall = and i16 %x, 7575  %xx = lshr i16 513, %xsmall576 577  %and = and i16 %y, %xx578  %r = icmp eq i16 %and, %xx579  ret i1 %r580}581 582define i1 @and_is_pow2(i16 %x, i16 %y) {583; CHECK-LABEL: define i1 @and_is_pow2584; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {585; CHECK-NEXT:    [[XNZ:%.*]] = or i16 [[X]], 4586; CHECK-NEXT:    [[X_NEG:%.*]] = sub nsw i16 0, [[XNZ]]587; CHECK-NEXT:    [[TMP1:%.*]] = and i16 [[Y]], [[X_NEG]]588; CHECK-NEXT:    [[AND:%.*]] = and i16 [[TMP1]], [[XNZ]]589; CHECK-NEXT:    [[R:%.*]] = icmp ne i16 [[AND]], 0590; CHECK-NEXT:    ret i1 [[R]]591;592  %xnz = or i16 %x, 4593  %x_neg = sub i16 0, %xnz594  %xx = and i16 %xnz, %x_neg595 596  %and = and i16 %y, %xx597  %r = icmp eq i16 %and, %xx598  ret i1 %r599}600 601define i1 @and_is_pow2_fail(i16 %x, i16 %y) {602; CHECK-LABEL: define i1 @and_is_pow2_fail603; CHECK-SAME: (i16 [[X:%.*]], i16 [[Y:%.*]]) {604; CHECK-NEXT:    [[X_NEG:%.*]] = sub i16 0, [[X]]605; CHECK-NEXT:    [[XX:%.*]] = and i16 [[X]], [[X_NEG]]606; CHECK-NEXT:    [[AND:%.*]] = and i16 [[Y]], [[XX]]607; CHECK-NEXT:    [[R:%.*]] = icmp eq i16 [[AND]], [[XX]]608; CHECK-NEXT:    ret i1 [[R]]609;610  %x_neg = sub i16 0, %x611  %xx = and i16 %x, %x_neg612 613  %and = and i16 %y, %xx614  %r = icmp eq i16 %and, %xx615  ret i1 %r616}617 618define i16 @i1_is_pow2_or_zero(i1 %x, i16 %y) {619; CHECK-LABEL: define i16 @i1_is_pow2_or_zero620; CHECK-SAME: (i1 [[X:%.*]], i16 [[Y:%.*]]) {621; CHECK-NEXT:    [[XX:%.*]] = zext i1 [[X]] to i16622; CHECK-NEXT:    [[R:%.*]] = or i16 [[Y]], [[XX]]623; CHECK-NEXT:    ret i16 [[R]]624;625  %xx = zext i1 %x to i16626  %yy = xor i16 %y, %xx627  %r = call i16 @llvm.umax.i16(i16 %yy, i16 %y)628  ret i16 %r629}630 631define i16 @i1_is_pow2_or_zero2(i1 %x, i16 %y0, i16 %z) {632; CHECK-LABEL: define i16 @i1_is_pow2_or_zero2633; CHECK-SAME: (i1 [[X:%.*]], i16 [[Y0:%.*]], i16 [[Z:%.*]]) {634; CHECK-NEXT:    [[XX:%.*]] = zext i1 [[X]] to i16635; CHECK-NEXT:    [[Y:%.*]] = or i16 [[Y0]], [[Z]]636; CHECK-NEXT:    [[R:%.*]] = or i16 [[Y]], [[XX]]637; CHECK-NEXT:    ret i16 [[R]]638;639  %xx = zext i1 %x to i16640  %y = or i16 %y0, %z641  %yy = xor i16 %y, %xx642  %r = call i16 @llvm.umax.i16(i16 %yy, i16 %y)643  ret i16 %r644}645