brintos

brintos / llvm-project-archived public Read only

0
0
Text · 52.0 KiB · df697e6 Raw
1575 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -passes=instcombine -S | FileCheck %s3 4define i1 @is_pow2or0_negate_op(i32 %x) {5; CHECK-LABEL: @is_pow2or0_negate_op(6; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])7; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[TMP1]], 28; CHECK-NEXT:    ret i1 [[CMP]]9;10  %neg = sub i32 0, %x11  %and = and i32 %neg, %x12  %cmp = icmp eq i32 %and, %x13  ret i1 %cmp14}15 16define <2 x i1> @is_pow2or0_negate_op_vec(<2 x i32> %x) {17; CHECK-LABEL: @is_pow2or0_negate_op_vec(18; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])19; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult <2 x i32> [[TMP1]], splat (i32 2)20; CHECK-NEXT:    ret <2 x i1> [[CMP]]21;22  %neg = sub <2 x i32> zeroinitializer, %x23  %and = and <2 x i32> %neg, %x24  %cmp = icmp eq <2 x i32> %and, %x25  ret <2 x i1> %cmp26}27 28define i1 @is_pow2or0_decrement_op(i8 %x) {29; CHECK-LABEL: @is_pow2or0_decrement_op(30; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])31; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i8 [[TMP1]], 232; CHECK-NEXT:    ret i1 [[CMP]]33;34  %dec = add i8 %x, -135  %and = and i8 %dec, %x36  %cmp = icmp eq i8 %and, 037  ret i1 %cmp38}39 40define <2 x i1> @is_pow2or0_decrement_op_vec(<2 x i8> %x) {41; CHECK-LABEL: @is_pow2or0_decrement_op_vec(42; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])43; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult <2 x i8> [[TMP1]], splat (i8 2)44; CHECK-NEXT:    ret <2 x i1> [[CMP]]45;46  %dec = add <2 x i8> %x, <i8 -1, i8 -1>47  %and = and <2 x i8> %dec, %x48  %cmp = icmp eq <2 x i8> %and, zeroinitializer49  ret <2 x i1> %cmp50}51 52define i1 @isnot_pow2or0_negate_op(i32 %x) {53; CHECK-LABEL: @isnot_pow2or0_negate_op(54; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])55; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[TMP1]], 156; CHECK-NEXT:    ret i1 [[CMP]]57;58  %neg = sub i32 0, %x59  %and = and i32 %neg, %x60  %cmp = icmp ne i32 %and, %x61  ret i1 %cmp62}63 64define <2 x i1> @isnot_pow2or0_negate_op_vec(<2 x i32> %x) {65; CHECK-LABEL: @isnot_pow2or0_negate_op_vec(66; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])67; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt <2 x i32> [[TMP1]], splat (i32 1)68; CHECK-NEXT:    ret <2 x i1> [[CMP]]69;70  %neg = sub <2 x i32> zeroinitializer, %x71  %and = and <2 x i32> %neg, %x72  %cmp = icmp ne <2 x i32> %and, %x73  ret <2 x i1> %cmp74}75 76define i1 @isnot_pow2or0_decrement_op(i8 %x) {77; CHECK-LABEL: @isnot_pow2or0_decrement_op(78; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])79; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i8 [[TMP1]], 180; CHECK-NEXT:    ret i1 [[CMP]]81;82  %dec = add i8 %x, -183  %and = and i8 %dec, %x84  %cmp = icmp ne i8 %and, 085  ret i1 %cmp86}87 88define <2 x i1> @isnot_pow2or0_decrement_op_vec(<2 x i8> %x) {89; CHECK-LABEL: @isnot_pow2or0_decrement_op_vec(90; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])91; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt <2 x i8> [[TMP1]], splat (i8 1)92; CHECK-NEXT:    ret <2 x i1> [[CMP]]93;94  %dec = add <2 x i8> %x, <i8 -1, i8 -1>95  %and = and <2 x i8> %dec, %x96  %cmp = icmp ne <2 x i8> %and, zeroinitializer97  ret <2 x i1> %cmp98}99 100define i1 @is_pow2or0_negate_op_commute1(i32 %p) {101; CHECK-LABEL: @is_pow2or0_negate_op_commute1(102; CHECK-NEXT:    [[X:%.*]] = srem i32 42, [[P:%.*]]103; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 7) i32 @llvm.ctpop.i32(i32 [[X]])104; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[TMP1]], 2105; CHECK-NEXT:    ret i1 [[CMP]]106;107  %x = srem i32 42, %p ; thwart complexity-based canonicalization108  %neg = sub i32 0, %x109  %and = and i32 %x, %neg110  %cmp = icmp eq i32 %and, %x111  ret i1 %cmp112}113 114; x can't be <= complexity of the 'neg' but >= complexity of the 'and'.115 116define i1 @isnot_pow2or0_negate_op_commute2(i32 %p) {117; CHECK-LABEL: @isnot_pow2or0_negate_op_commute2(118; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[P:%.*]]119; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 7) i32 @llvm.ctpop.i32(i32 [[X]])120; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[TMP1]], 1121; CHECK-NEXT:    ret i1 [[CMP]]122;123  %x = urem i32 42, %p ; thwart complexity-based canonicalization124  %neg = sub i32 0, %x125  %and = and i32 %neg, %x126  %cmp = icmp ne i32 %x, %and127  ret i1 %cmp128}129 130define i1 @isnot_pow2or0_negate_op_commute3(i32 %p) {131; CHECK-LABEL: @isnot_pow2or0_negate_op_commute3(132; CHECK-NEXT:    [[X:%.*]] = urem i32 42, [[P:%.*]]133; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 7) i32 @llvm.ctpop.i32(i32 [[X]])134; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[TMP1]], 1135; CHECK-NEXT:    ret i1 [[CMP]]136;137  %x = urem i32 42, %p ; thwart complexity-based canonicalization138  %neg = sub i32 0, %x139  %and = and i32 %x, %neg140  %cmp = icmp ne i32 %x, %and141  ret i1 %cmp142}143 144declare void @use(i32)145 146define i1 @is_pow2or0_negate_op_extra_use1(i32 %x) {147; CHECK-LABEL: @is_pow2or0_negate_op_extra_use1(148; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]149; CHECK-NEXT:    call void @use(i32 [[NEG]])150; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])151; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[TMP1]], 2152; CHECK-NEXT:    ret i1 [[CMP]]153;154  %neg = sub i32 0, %x155  call void @use(i32 %neg)156  %and = and i32 %neg, %x157  %cmp = icmp eq i32 %and, %x158  ret i1 %cmp159}160 161define i1 @is_pow2or0_negate_op_extra_use2(i32 %x) {162; CHECK-LABEL: @is_pow2or0_negate_op_extra_use2(163; CHECK-NEXT:    [[NEG:%.*]] = sub i32 0, [[X:%.*]]164; CHECK-NEXT:    [[AND:%.*]] = and i32 [[X]], [[NEG]]165; CHECK-NEXT:    call void @use(i32 [[AND]])166; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[AND]], [[X]]167; CHECK-NEXT:    ret i1 [[CMP]]168;169  %neg = sub i32 0, %x170  %and = and i32 %neg, %x171  call void @use(i32 %and)172  %cmp = icmp eq i32 %and, %x173  ret i1 %cmp174}175 176declare i32 @llvm.ctpop.i32(i32)177declare <2 x i8> @llvm.ctpop.v2i8(<2 x i8>)178declare void @llvm.assume(i1)179 180; (X != 0) && (ctpop(X) u< 2) --> ctpop(X) == 1181 182define i1 @is_pow2_ctpop(i32 %x) {183; CHECK-LABEL: @is_pow2_ctpop(184; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])185; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1186; CHECK-NEXT:    ret i1 [[R]]187;188  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)189  %cmp = icmp ult i32 %t0, 2190  %notzero = icmp ne i32 %x, 0191  %r = and i1 %notzero, %cmp192  ret i1 %r193}194 195; tests from PR57328196define i1 @is_pow2_non_zero_ult_2(i32 %x) {197; CHECK-LABEL: @is_pow2_non_zero_ult_2(198; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0199; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])200; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])201; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2202; CHECK-NEXT:    ret i1 [[CMP]]203;204  %notzero = icmp ne i32 %x, 0205  call void @llvm.assume(i1 %notzero)206  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)207  %cmp = icmp ult i32 %t0, 2208  ret i1 %cmp209}210 211define i1 @is_pow2_non_zero_eq_1(i32 %x) {212; CHECK-LABEL: @is_pow2_non_zero_eq_1(213; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0214; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])215; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])216; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1217; CHECK-NEXT:    ret i1 [[CMP]]218;219  %notzero = icmp ne i32 %x, 0220  call void @llvm.assume(i1 %notzero)221  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)222  %cmp = icmp eq i32 %t0, 1223  ret i1 %cmp224}225 226define i1 @is_pow2_non_zero_ugt_1(i32 %x) {227; CHECK-LABEL: @is_pow2_non_zero_ugt_1(228; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0229; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])230; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])231; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1232; CHECK-NEXT:    ret i1 [[CMP]]233;234  %notzero = icmp ne i32 %x, 0235  call void @llvm.assume(i1 %notzero)236  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)237  %cmp = icmp ugt i32 %t0, 1238  ret i1 %cmp239}240 241define i1 @is_pow2_non_zero_ne_1(i32 %x) {242; CHECK-LABEL: @is_pow2_non_zero_ne_1(243; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X:%.*]], 0244; CHECK-NEXT:    call void @llvm.assume(i1 [[NOTZERO]])245; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])246; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 1247; CHECK-NEXT:    ret i1 [[CMP]]248;249  %notzero = icmp ne i32 %x, 0250  call void @llvm.assume(i1 %notzero)251  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)252  %cmp = icmp ne i32 %t0, 1253  ret i1 %cmp254}255 256define i1 @is_pow2_ctpop_logical(i32 %x) {257; CHECK-LABEL: @is_pow2_ctpop_logical(258; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])259; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1260; CHECK-NEXT:    ret i1 [[R]]261;262  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)263  %cmp = icmp ult i32 %t0, 2264  %notzero = icmp ne i32 %x, 0265  %r = select i1 %notzero, i1 %cmp, i1 false266  ret i1 %r267}268 269; Extra uses don't change the fold.270declare void @use_i1(i1)271 272define i1 @is_pow2_ctpop_extra_uses(i32 %x) {273; CHECK-LABEL: @is_pow2_ctpop_extra_uses(274; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])275; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2276; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])277; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0278; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])279; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1280; CHECK-NEXT:    ret i1 [[R]]281;282  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)283  %cmp = icmp ult i32 %t0, 2284  call void @use_i1(i1 %cmp)285  %notzero = icmp ne i32 %x, 0286  call void @use_i1(i1 %notzero)287  %r = and i1 %notzero, %cmp288  ret i1 %r289}290 291define i1 @is_pow2_ctpop_extra_uses_logical(i32 %x) {292; CHECK-LABEL: @is_pow2_ctpop_extra_uses_logical(293; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])294; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2295; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])296; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0297; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])298; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[T0]], 1299; CHECK-NEXT:    ret i1 [[R]]300;301  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)302  %cmp = icmp ult i32 %t0, 2303  call void @use_i1(i1 %cmp)304  %notzero = icmp ne i32 %x, 0305  call void @use_i1(i1 %notzero)306  %r = select i1 %notzero, i1 %cmp, i1 false307  ret i1 %r308}309 310; Test vector type and commuted 'and' operands.311 312define <2 x i1> @is_pow2_ctpop_commute_vec(<2 x i8> %x) {313; CHECK-LABEL: @is_pow2_ctpop_commute_vec(314; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])315; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[T0]], splat (i8 1)316; CHECK-NEXT:    ret <2 x i1> [[R]]317;318  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)319  %cmp = icmp ult <2 x i8> %t0, <i8 2, i8 2>320  %notzero = icmp ne <2 x i8> %x, zeroinitializer321  %r = and <2 x i1> %cmp, %notzero322  ret <2 x i1> %r323}324 325; Negative test - wrong constant.326 327define i1 @is_pow2_ctpop_wrong_cmp_op1(i32 %x) {328; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op1(329; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])330; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 3331; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0332; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]333; CHECK-NEXT:    ret i1 [[R]]334;335  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)336  %cmp = icmp ult i32 %t0, 3337  %notzero = icmp ne i32 %x, 0338  %r = and i1 %notzero, %cmp339  ret i1 %r340}341 342define i1 @is_pow2_ctpop_wrong_cmp_op1_logical(i32 %x) {343; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op1_logical(344; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])345; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 3346; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 0347; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTZERO]], i1 [[CMP]], i1 false348; CHECK-NEXT:    ret i1 [[R]]349;350  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)351  %cmp = icmp ult i32 %t0, 3352  %notzero = icmp ne i32 %x, 0353  %r = select i1 %notzero, i1 %cmp, i1 false354  ret i1 %r355}356 357; Negative test - wrong constant.358 359define i1 @is_pow2_ctpop_wrong_cmp_op2(i32 %x) {360; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op2(361; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])362; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2363; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 1364; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]365; CHECK-NEXT:    ret i1 [[R]]366;367  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)368  %cmp = icmp ult i32 %t0, 2369  %notzero = icmp ne i32 %x, 1370  %r = and i1 %notzero, %cmp371  ret i1 %r372}373 374define i1 @is_pow2_ctpop_wrong_cmp_op2_logical(i32 %x) {375; CHECK-LABEL: @is_pow2_ctpop_wrong_cmp_op2_logical(376; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])377; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2378; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 1379; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTZERO]], i1 [[CMP]], i1 false380; CHECK-NEXT:    ret i1 [[R]]381;382  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)383  %cmp = icmp ult i32 %t0, 2384  %notzero = icmp ne i32 %x, 1385  %r = select i1 %notzero, i1 %cmp, i1 false386  ret i1 %r387}388 389; Negative test - wrong predicate.390 391define i1 @is_pow2_ctpop_wrong_pred1(i32 %x) {392; CHECK-LABEL: @is_pow2_ctpop_wrong_pred1(393; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])394; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2395; CHECK-NEXT:    ret i1 [[CMP]]396;397  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)398  %cmp = icmp ugt i32 %t0, 2399  %notzero = icmp ne i32 %x, 0400  %r = and i1 %notzero, %cmp401  ret i1 %r402}403 404define i1 @is_pow2_ctpop_wrong_pred1_logical(i32 %x) {405; CHECK-LABEL: @is_pow2_ctpop_wrong_pred1_logical(406; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])407; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2408; CHECK-NEXT:    ret i1 [[CMP]]409;410  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)411  %cmp = icmp ugt i32 %t0, 2412  %notzero = icmp ne i32 %x, 0413  %r = select i1 %notzero, i1 %cmp, i1 false414  ret i1 %r415}416 417; Negative test - wrong predicate.418 419define i1 @is_pow2_ctpop_wrong_pred2(i32 %x) {420; CHECK-LABEL: @is_pow2_ctpop_wrong_pred2(421; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])422; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2423; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], 0424; CHECK-NEXT:    [[R:%.*]] = and i1 [[CMP2]], [[CMP]]425; CHECK-NEXT:    ret i1 [[R]]426;427  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)428  %cmp = icmp ult i32 %t0, 2429  %cmp2 = icmp sgt i32 %x, 0430  %r = and i1 %cmp2, %cmp431  ret i1 %r432}433 434define i1 @is_pow2_ctpop_wrong_pred2_logical(i32 %x) {435; CHECK-LABEL: @is_pow2_ctpop_wrong_pred2_logical(436; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])437; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ult i32 [[T0]], 2438; CHECK-NEXT:    [[CMP2:%.*]] = icmp sgt i32 [[X]], 0439; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP2]], i1 [[CMP]], i1 false440; CHECK-NEXT:    ret i1 [[R]]441;442  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)443  %cmp = icmp ult i32 %t0, 2444  %cmp2 = icmp sgt i32 %x, 0445  %r = select i1 %cmp2, i1 %cmp, i1 false446  ret i1 %r447}448 449; (X == 0) || (ctpop(X) u> 1) --> ctpop(X) != 1450 451define i1 @isnot_pow2_ctpop(i32 %x) {452; CHECK-LABEL: @isnot_pow2_ctpop(453; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])454; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1455; CHECK-NEXT:    ret i1 [[R]]456;457  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)458  %cmp = icmp ugt i32 %t0, 1459  %iszero = icmp eq i32 %x, 0460  %r = or i1 %iszero, %cmp461  ret i1 %r462}463 464define i1 @isnot_pow2_ctpop_logical(i32 %x) {465; CHECK-LABEL: @isnot_pow2_ctpop_logical(466; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])467; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1468; CHECK-NEXT:    ret i1 [[R]]469;470  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)471  %cmp = icmp ugt i32 %t0, 1472  %iszero = icmp eq i32 %x, 0473  %r = select i1 %iszero, i1 true, i1 %cmp474  ret i1 %r475}476 477; Extra uses don't change the fold.478 479define i1 @isnot_pow2_ctpop_extra_uses(i32 %x) {480; CHECK-LABEL: @isnot_pow2_ctpop_extra_uses(481; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])482; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1483; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])484; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0485; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])486; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1487; CHECK-NEXT:    ret i1 [[R]]488;489  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)490  %cmp = icmp ugt i32 %t0, 1491  call void @use_i1(i1 %cmp)492  %iszero = icmp eq i32 %x, 0493  call void @use_i1(i1 %iszero)494  %r = or i1 %iszero, %cmp495  ret i1 %r496}497 498define i1 @isnot_pow2_ctpop_extra_uses_logical(i32 %x) {499; CHECK-LABEL: @isnot_pow2_ctpop_extra_uses_logical(500; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])501; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1502; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])503; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0504; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])505; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[T0]], 1506; CHECK-NEXT:    ret i1 [[R]]507;508  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)509  %cmp = icmp ugt i32 %t0, 1510  call void @use_i1(i1 %cmp)511  %iszero = icmp eq i32 %x, 0512  call void @use_i1(i1 %iszero)513  %r = select i1 %iszero, i1 true, i1 %cmp514  ret i1 %r515}516 517; Test vector type and commuted 'or' operands.518 519define <2 x i1> @isnot_pow2_ctpop_commute_vec(<2 x i8> %x) {520; CHECK-LABEL: @isnot_pow2_ctpop_commute_vec(521; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])522; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[T0]], splat (i8 1)523; CHECK-NEXT:    ret <2 x i1> [[R]]524;525  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)526  %cmp = icmp ugt <2 x i8> %t0, <i8 1, i8 1>527  %iszero = icmp eq <2 x i8> %x, zeroinitializer528  %r = or <2 x i1> %cmp, %iszero529  ret <2 x i1> %r530}531 532; Negative test - wrong constant.533 534define i1 @isnot_pow2_ctpop_wrong_cmp_op1(i32 %x) {535; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op1(536; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])537; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2538; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0539; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]540; CHECK-NEXT:    ret i1 [[R]]541;542  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)543  %cmp = icmp ugt i32 %t0, 2544  %iszero = icmp eq i32 %x, 0545  %r = or i1 %iszero, %cmp546  ret i1 %r547}548 549define i1 @isnot_pow2_ctpop_wrong_cmp_op1_logical(i32 %x) {550; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op1_logical(551; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])552; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 2553; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0554; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISZERO]], i1 true, i1 [[CMP]]555; CHECK-NEXT:    ret i1 [[R]]556;557  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)558  %cmp = icmp ugt i32 %t0, 2559  %iszero = icmp eq i32 %x, 0560  %r = select i1 %iszero, i1 true, i1 %cmp561  ret i1 %r562}563 564; Negative test - wrong constant.565 566define i1 @isnot_pow2_ctpop_wrong_cmp_op2(i32 %x) {567; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op2(568; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])569; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1570; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 1571; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]572; CHECK-NEXT:    ret i1 [[R]]573;574  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)575  %cmp = icmp ugt i32 %t0, 1576  %iszero = icmp eq i32 %x, 1577  %r = or i1 %iszero, %cmp578  ret i1 %r579}580 581define i1 @isnot_pow2_ctpop_wrong_cmp_op2_logical(i32 %x) {582; CHECK-LABEL: @isnot_pow2_ctpop_wrong_cmp_op2_logical(583; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])584; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1585; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 1586; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISZERO]], i1 true, i1 [[CMP]]587; CHECK-NEXT:    ret i1 [[R]]588;589  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)590  %cmp = icmp ugt i32 %t0, 1591  %iszero = icmp eq i32 %x, 1592  %r = select i1 %iszero, i1 true, i1 %cmp593  ret i1 %r594}595 596; Negative test - wrong predicate.597 598define i1 @isnot_pow2_ctpop_wrong_pred2(i32 %x) {599; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred2(600; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])601; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1602; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 0603; CHECK-NEXT:    [[R:%.*]] = or i1 [[CMP2]], [[CMP]]604; CHECK-NEXT:    ret i1 [[R]]605;606  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)607  %cmp = icmp ugt i32 %t0, 1608  %cmp2 = icmp slt i32 %x, 0609  %r = or i1 %cmp2, %cmp610  ret i1 %r611}612 613define i1 @isnot_pow2_ctpop_wrong_pred2_logical(i32 %x) {614; CHECK-LABEL: @isnot_pow2_ctpop_wrong_pred2_logical(615; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])616; CHECK-NEXT:    [[CMP:%.*]] = icmp samesign ugt i32 [[T0]], 1617; CHECK-NEXT:    [[CMP2:%.*]] = icmp slt i32 [[X]], 0618; CHECK-NEXT:    [[R:%.*]] = select i1 [[CMP2]], i1 true, i1 [[CMP]]619; CHECK-NEXT:    ret i1 [[R]]620;621  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)622  %cmp = icmp ugt i32 %t0, 1623  %cmp2 = icmp slt i32 %x, 0624  %r = select i1 %cmp2, i1 true, i1 %cmp625  ret i1 %r626}627 628define i1 @is_pow2_negate_op(i32 %x) {629; CHECK-LABEL: @is_pow2_negate_op(630; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])631; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 1632; CHECK-NEXT:    ret i1 [[R]]633;634  %neg = sub i32 0, %x635  %and = and i32 %neg, %x636  %cmp = icmp eq i32 %and, %x637  %notzero = icmp ne i32 %x, 0638  %r = and i1 %notzero, %cmp639  ret i1 %r640}641 642define i1 @is_pow2_negate_op_logical(i32 %x) {643; CHECK-LABEL: @is_pow2_negate_op_logical(644; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])645; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 1646; CHECK-NEXT:    ret i1 [[R]]647;648  %neg = sub i32 0, %x649  %and = and i32 %neg, %x650  %cmp = icmp eq i32 %and, %x651  %notzero = icmp ne i32 %x, 0652  %r = select i1 %notzero, i1 %cmp, i1 false653  ret i1 %r654}655 656define <2 x i1> @is_pow2_negate_op_vec(<2 x i32> %x) {657; CHECK-LABEL: @is_pow2_negate_op_vec(658; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])659; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i32> [[TMP1]], splat (i32 1)660; CHECK-NEXT:    ret <2 x i1> [[R]]661;662  %neg = sub <2 x i32> zeroinitializer, %x663  %and = and <2 x i32> %neg, %x664  %cmp = icmp eq <2 x i32> %and, %x665  %notzero = icmp ne <2 x i32> %x, zeroinitializer666  %r = and <2 x i1> %cmp, %notzero667  ret <2 x i1> %r668}669 670define i1 @is_pow2_decrement_op(i8 %x) {671; CHECK-LABEL: @is_pow2_decrement_op(672; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])673; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 1674; CHECK-NEXT:    ret i1 [[R]]675;676  %dec = add i8 %x, -1677  %and = and i8 %dec, %x678  %cmp = icmp eq i8 %and, 0679  %notzero = icmp ne i8 %x, 0680  %r = and i1 %cmp, %notzero681  ret i1 %r682}683 684define i1 @is_pow2_decrement_op_logical(i8 %x) {685; CHECK-LABEL: @is_pow2_decrement_op_logical(686; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])687; CHECK-NEXT:    [[R:%.*]] = icmp eq i8 [[TMP1]], 1688; CHECK-NEXT:    ret i1 [[R]]689;690  %dec = add i8 %x, -1691  %and = and i8 %dec, %x692  %cmp = icmp eq i8 %and, 0693  %notzero = icmp ne i8 %x, 0694  %r = select i1 %cmp, i1 %notzero, i1 false695  ret i1 %r696}697 698define <2 x i1> @is_pow2_decrement_op_vec(<2 x i8> %x) {699; CHECK-LABEL: @is_pow2_decrement_op_vec(700; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])701; CHECK-NEXT:    [[R:%.*]] = icmp eq <2 x i8> [[TMP1]], splat (i8 1)702; CHECK-NEXT:    ret <2 x i1> [[R]]703;704  %dec = add <2 x i8> %x, <i8 -1, i8 -1>705  %and = and <2 x i8> %dec, %x706  %cmp = icmp eq <2 x i8> %and, zeroinitializer707  %notzero = icmp ne <2 x i8> %x, zeroinitializer708  %r = and <2 x i1> %notzero, %cmp709  ret <2 x i1> %r710}711 712define i1 @isnot_pow2_negate_op(i32 %x) {713; CHECK-LABEL: @isnot_pow2_negate_op(714; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])715; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 1716; CHECK-NEXT:    ret i1 [[R]]717;718  %neg = sub i32 0, %x719  %and = and i32 %neg, %x720  %cmp = icmp ne i32 %and, %x721  %iszero = icmp eq i32 %x, 0722  %r = or i1 %cmp, %iszero723  ret i1 %r724}725 726define i1 @isnot_pow2_negate_op_logical(i32 %x) {727; CHECK-LABEL: @isnot_pow2_negate_op_logical(728; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])729; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[TMP1]], 1730; CHECK-NEXT:    ret i1 [[R]]731;732  %neg = sub i32 0, %x733  %and = and i32 %neg, %x734  %cmp = icmp ne i32 %and, %x735  %iszero = icmp eq i32 %x, 0736  %r = select i1 %cmp, i1 true, i1 %iszero737  ret i1 %r738}739 740define <2 x i1> @isnot_pow2_negate_op_vec(<2 x i32> %x) {741; CHECK-LABEL: @isnot_pow2_negate_op_vec(742; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X:%.*]])743; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], splat (i32 1)744; CHECK-NEXT:    ret <2 x i1> [[R]]745;746  %neg = sub <2 x i32> zeroinitializer, %x747  %and = and <2 x i32> %neg, %x748  %cmp = icmp ne <2 x i32> %and, %x749  %iszero = icmp eq <2 x i32> %x, zeroinitializer750  %r = or <2 x i1> %iszero, %cmp751  ret <2 x i1> %r752}753 754define i1 @isnot_pow2_decrement_op(i8 %x) {755; CHECK-LABEL: @isnot_pow2_decrement_op(756; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])757; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[TMP1]], 1758; CHECK-NEXT:    ret i1 [[R]]759;760  %dec = add i8 %x, -1761  %and = and i8 %dec, %x762  %cmp = icmp ne i8 %and, 0763  %iszero = icmp eq i8 %x, 0764  %r = or i1 %iszero, %cmp765  ret i1 %r766}767 768define i1 @isnot_pow2_decrement_op_logical(i8 %x) {769; CHECK-LABEL: @isnot_pow2_decrement_op_logical(770; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X:%.*]])771; CHECK-NEXT:    [[R:%.*]] = icmp ne i8 [[TMP1]], 1772; CHECK-NEXT:    ret i1 [[R]]773;774  %dec = add i8 %x, -1775  %and = and i8 %dec, %x776  %cmp = icmp ne i8 %and, 0777  %iszero = icmp eq i8 %x, 0778  %r = select i1 %iszero, i1 true, i1 %cmp779  ret i1 %r780}781 782define <2 x i1> @isnot_pow2_decrement_op_vec(<2 x i8> %x) {783; CHECK-LABEL: @isnot_pow2_decrement_op_vec(784; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])785; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i8> [[TMP1]], splat (i8 1)786; CHECK-NEXT:    ret <2 x i1> [[R]]787;788  %dec = add <2 x i8> %x, <i8 -1, i8 -1>789  %and = and <2 x i8> %dec, %x790  %cmp = icmp ne <2 x i8> %and, zeroinitializer791  %iszero = icmp eq <2 x i8> %x, zeroinitializer792  %r = or <2 x i1> %cmp, %iszero793  ret <2 x i1> %r794}795 796; (ctpop(X) == 1) || (X == 0) --> ctpop(X) u< 2797 798define i1 @is_pow2or0_ctpop(i32 %x) {799; CHECK-LABEL: @is_pow2or0_ctpop(800; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])801; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2802; CHECK-NEXT:    ret i1 [[R]]803;804  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)805  %cmp = icmp eq i32 %t0, 1806  %iszero = icmp eq i32 %x, 0807  %r = or i1 %iszero, %cmp808  ret i1 %r809}810 811define i1 @is_pow2or0_ctpop_swap_cmp(i32 %x) {812; CHECK-LABEL: @is_pow2or0_ctpop_swap_cmp(813; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])814; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2815; CHECK-NEXT:    ret i1 [[R]]816;817  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)818  %cmp = icmp eq i32 %t0, 1819  %iszero = icmp eq i32 %x, 0820  %r = or i1 %cmp, %iszero821  ret i1 %r822}823 824define i1 @is_pow2or0_ctpop_logical(i32 %x) {825; CHECK-LABEL: @is_pow2or0_ctpop_logical(826; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])827; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2828; CHECK-NEXT:    ret i1 [[R]]829;830  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)831  %cmp = icmp eq i32 %t0, 1832  %iszero = icmp eq i32 %x, 0833  %r = select i1 %iszero, i1 true, i1 %cmp834  ret i1 %r835}836 837define <2 x i1> @is_pow2or0_ctpop_commute_vec(<2 x i8> %x) {838; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec(839; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])840; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult <2 x i8> [[T0]], splat (i8 2)841; CHECK-NEXT:    ret <2 x i1> [[R]]842;843  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)844  %cmp = icmp eq <2 x i8> %t0, <i8 1, i8 1>845  %iszero = icmp eq <2 x i8> %x, <i8 0, i8 0>846  %r = or <2 x i1> %iszero, %cmp847  ret <2 x i1> %r848}849 850; Extra uses don't change the fold.851 852define i1 @is_pow2or0_ctpop_extra_uses(i32 %x) {853; CHECK-LABEL: @is_pow2or0_ctpop_extra_uses(854; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])855; CHECK-NEXT:    call void @use(i32 [[T0]])856; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1857; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])858; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0859; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])860; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2861; CHECK-NEXT:    ret i1 [[R]]862;863  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)864  call void @use(i32 %t0)865  %cmp = icmp eq i32 %t0, 1866  call void @use_i1(i1 %cmp)867  %iszero = icmp eq i32 %x, 0868  call void @use_i1(i1 %iszero)869  %r = or i1 %iszero, %cmp870  ret i1 %r871}872 873define i1 @is_pow2or0_ctpop_logical_extra_uses(i32 %x) {874; CHECK-LABEL: @is_pow2or0_ctpop_logical_extra_uses(875; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])876; CHECK-NEXT:    call void @use(i32 [[T0]])877; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 1878; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])879; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0880; CHECK-NEXT:    call void @use_i1(i1 [[ISZERO]])881; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i32 [[T0]], 2882; CHECK-NEXT:    ret i1 [[R]]883;884  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)885  call void @use(i32 %t0)886  %cmp = icmp eq i32 %t0, 1887  call void @use_i1(i1 %cmp)888  %iszero = icmp eq i32 %x, 0889  call void @use_i1(i1 %iszero)890  %r = select i1 %iszero, i1 true, i1 %cmp891  ret i1 %r892}893 894; Negative test - wrong constant.895 896define i1 @is_pow2or0_ctpop_wrong_cmp_op1(i32 %x) {897; CHECK-LABEL: @is_pow2or0_ctpop_wrong_cmp_op1(898; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])899; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 2900; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0901; CHECK-NEXT:    [[R:%.*]] = or i1 [[ISZERO]], [[CMP]]902; CHECK-NEXT:    ret i1 [[R]]903;904  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)905  %cmp = icmp eq i32 %t0, 2906  %iszero = icmp eq i32 %x, 0907  %r = or i1 %iszero, %cmp908  ret i1 %r909}910 911define i1 @is_pow2or0_ctpop_wrong_cmp_op1_logical(i32 %x) {912; CHECK-LABEL: @is_pow2or0_ctpop_wrong_cmp_op1_logical(913; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])914; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 3915; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq i32 [[X]], 0916; CHECK-NEXT:    [[R:%.*]] = select i1 [[ISZERO]], i1 true, i1 [[CMP]]917; CHECK-NEXT:    ret i1 [[R]]918;919  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)920  %cmp = icmp eq i32 %t0, 3921  %iszero = icmp eq i32 %x, 0922  %r = select i1 %iszero, i1 true, i1 %cmp923  ret i1 %r924}925 926define <2 x i1> @is_pow2or0_ctpop_commute_vec_wrong_cmp_op1(<2 x i8> %x) {927; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec_wrong_cmp_op1(928; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])929; CHECK-NEXT:    [[CMP:%.*]] = icmp eq <2 x i8> [[T0]], <i8 -1, i8 1>930; CHECK-NEXT:    [[ISZERO:%.*]] = icmp eq <2 x i8> [[X]], zeroinitializer931; CHECK-NEXT:    [[R:%.*]] = or <2 x i1> [[CMP]], [[ISZERO]]932; CHECK-NEXT:    ret <2 x i1> [[R]]933;934  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)935  %cmp = icmp eq <2 x i8> %t0, <i8 -1, i8 1>936  %iszero = icmp eq <2 x i8> %x, <i8 0, i8 0>937  %r = or <2 x i1> %cmp, %iszero938  ret <2 x i1> %r939}940 941; Negative test - wrong predicate.942 943define i1 @is_pow2or0_ctpop_wrong_pred1(i32 %x) {944; CHECK-LABEL: @is_pow2or0_ctpop_wrong_pred1(945; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])946; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 1947; CHECK-NEXT:    ret i1 [[CMP]]948;949  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)950  %cmp = icmp ne i32 %t0, 1951  %iszero = icmp eq i32 %x, 0952  %r = or i1 %iszero, %cmp953  ret i1 %r954}955 956define i1 @is_pow2or0_ctpop_wrong_pred2(i32 %x) {957; CHECK-LABEL: @is_pow2or0_ctpop_wrong_pred2(958; CHECK-NEXT:    ret i1 true959;960  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)961  %cmp = icmp ne i32 %t0, 1962  %iszero = icmp ne i32 %x, 0963  %r = or i1 %iszero, %cmp964  ret i1 %r965}966 967define i1 @is_pow2or0_ctpop_wrong_pred2_logical(i32 %x) {968; CHECK-LABEL: @is_pow2or0_ctpop_wrong_pred2_logical(969; CHECK-NEXT:    ret i1 true970;971  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)972  %cmp = icmp ne i32 %t0, 1973  %iszero = icmp ne i32 %x, 0974  %r = select i1 %iszero, i1 true, i1 %cmp975  ret i1 %r976}977 978define <2 x i1> @is_pow2or0_ctpop_commute_vec_wrong_pred3(<2 x i8> %x) {979; CHECK-LABEL: @is_pow2or0_ctpop_commute_vec_wrong_pred3(980; CHECK-NEXT:    ret <2 x i1> zeroinitializer981;982  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)983  %cmp = icmp eq <2 x i8> %t0, <i8 1, i8 1>984  %iszero = icmp eq <2 x i8> %x, <i8 0, i8 0>985  %r = and <2 x i1> %cmp, %iszero986  ret <2 x i1> %r987}988 989; (ctpop(X) != 1) && (X != 0) --> ctpop(X) u> 1990 991define i1 @isnot_pow2nor0_ctpop(i32 %x) {992; CHECK-LABEL: @isnot_pow2nor0_ctpop(993; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])994; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 1995; CHECK-NEXT:    ret i1 [[R]]996;997  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)998  %cmp = icmp ne i32 %t0, 1999  %notzero = icmp ne i32 %x, 01000  %r = and i1 %notzero, %cmp1001  ret i1 %r1002}1003 1004define i1 @isnot_pow2nor0_ctpop_swap_cmp(i32 %x) {1005; CHECK-LABEL: @isnot_pow2nor0_ctpop_swap_cmp(1006; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1007; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 11008; CHECK-NEXT:    ret i1 [[R]]1009;1010  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1011  %cmp = icmp ne i32 %t0, 11012  %notzero = icmp ne i32 %x, 01013  %r = and i1 %cmp, %notzero1014  ret i1 %r1015}1016 1017define i1 @isnot_pow2nor0_ctpop_logical(i32 %x) {1018; CHECK-LABEL: @isnot_pow2nor0_ctpop_logical(1019; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1020; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 11021; CHECK-NEXT:    ret i1 [[R]]1022;1023  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1024  %cmp = icmp ne i32 %t0, 11025  %notzero = icmp ne i32 %x, 01026  %r = select i1 %notzero, i1 %cmp, i1 false1027  ret i1 %r1028}1029 1030define <2 x i1> @isnot_pow2nor0_ctpop_commute_vec(<2 x i8> %x) {1031; CHECK-LABEL: @isnot_pow2nor0_ctpop_commute_vec(1032; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])1033; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt <2 x i8> [[T0]], splat (i8 1)1034; CHECK-NEXT:    ret <2 x i1> [[R]]1035;1036  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)1037  %cmp = icmp ne <2 x i8> %t0, <i8 1, i8 1>1038  %notzero = icmp ne <2 x i8> %x, <i8 0, i8 0>1039  %r = and <2 x i1> %notzero, %cmp1040  ret <2 x i1> %r1041}1042 1043; Extra uses don't change the fold.1044 1045define i1 @isnot_pow2nor0_ctpop_extra_uses(i32 %x) {1046; CHECK-LABEL: @isnot_pow2nor0_ctpop_extra_uses(1047; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1048; CHECK-NEXT:    call void @use(i32 [[T0]])1049; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 11050; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])1051; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 01052; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])1053; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 11054; CHECK-NEXT:    ret i1 [[R]]1055;1056  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1057  call void @use(i32 %t0)1058  %cmp = icmp ne i32 %t0, 11059  call void @use_i1(i1 %cmp)1060  %notzero = icmp ne i32 %x, 01061  call void @use_i1(i1 %notzero)1062  %r = and i1 %notzero, %cmp1063  ret i1 %r1064}1065 1066define i1 @isnot_pow2nor0_ctpop_logical_extra_uses(i32 %x) {1067; CHECK-LABEL: @isnot_pow2nor0_ctpop_logical_extra_uses(1068; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1069; CHECK-NEXT:    call void @use(i32 [[T0]])1070; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 11071; CHECK-NEXT:    call void @use_i1(i1 [[CMP]])1072; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 01073; CHECK-NEXT:    call void @use_i1(i1 [[NOTZERO]])1074; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[T0]], 11075; CHECK-NEXT:    ret i1 [[R]]1076;1077  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1078  call void @use(i32 %t0)1079  %cmp = icmp ne i32 %t0, 11080  call void @use_i1(i1 %cmp)1081  %notzero = icmp ne i32 %x, 01082  call void @use_i1(i1 %notzero)1083  %r = select i1 %notzero, i1 %cmp, i1 false1084  ret i1 %r1085}1086 1087; Negative test - wrong constant.1088 1089define i1 @isnot_pow2nor0_ctpop_wrong_cmp_op1(i32 %x) {1090; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_cmp_op1(1091; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1092; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 41093; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 01094; CHECK-NEXT:    [[R:%.*]] = and i1 [[NOTZERO]], [[CMP]]1095; CHECK-NEXT:    ret i1 [[R]]1096;1097  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1098  %cmp = icmp ne i32 %t0, 41099  %notzero = icmp ne i32 %x, 01100  %r = and i1 %notzero, %cmp1101  ret i1 %r1102}1103 1104define i1 @isnot_pow2nor0_ctpop_wrong_cmp_op1_logical(i32 %x) {1105; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_cmp_op1_logical(1106; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1107; CHECK-NEXT:    [[CMP:%.*]] = icmp ne i32 [[T0]], 51108; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne i32 [[X]], 01109; CHECK-NEXT:    [[R:%.*]] = select i1 [[NOTZERO]], i1 [[CMP]], i1 false1110; CHECK-NEXT:    ret i1 [[R]]1111;1112  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1113  %cmp = icmp ne i32 %t0, 51114  %notzero = icmp ne i32 %x, 01115  %r = select i1 %notzero, i1 %cmp, i1 false1116  ret i1 %r1117}1118 1119define <2 x i1> @isnot_pow2nor0_ctpop_commute_vec_wrong_cmp_op1(<2 x i8> %x) {1120; CHECK-LABEL: @isnot_pow2nor0_ctpop_commute_vec_wrong_cmp_op1(1121; CHECK-NEXT:    [[T0:%.*]] = tail call range(i8 0, 9) <2 x i8> @llvm.ctpop.v2i8(<2 x i8> [[X:%.*]])1122; CHECK-NEXT:    [[CMP:%.*]] = icmp ne <2 x i8> [[T0]], <i8 0, i8 -1>1123; CHECK-NEXT:    [[NOTZERO:%.*]] = icmp ne <2 x i8> [[X]], zeroinitializer1124; CHECK-NEXT:    [[R:%.*]] = and <2 x i1> [[CMP]], [[NOTZERO]]1125; CHECK-NEXT:    ret <2 x i1> [[R]]1126;1127  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)1128  %cmp = icmp ne <2 x i8> %t0, <i8 0, i8 -1>1129  %notzero = icmp ne <2 x i8> %x, <i8 0, i8 0>1130  %r = and <2 x i1> %cmp, %notzero1131  ret <2 x i1> %r1132}1133 1134; Negative test - wrong predicate.1135 1136define i1 @isnot_pow2nor0_ctpop_wrong_pred1(i32 %x) {1137; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_pred1(1138; CHECK-NEXT:    [[T0:%.*]] = tail call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1139; CHECK-NEXT:    [[CMP:%.*]] = icmp eq i32 [[T0]], 11140; CHECK-NEXT:    ret i1 [[CMP]]1141;1142  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1143  %cmp = icmp eq i32 %t0, 11144  %notzero = icmp ne i32 %x, 01145  %r = and i1 %notzero, %cmp1146  ret i1 %r1147}1148 1149define i1 @isnot_pow2nor0_ctpop_wrong_pred2(i32 %x) {1150; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_pred2(1151; CHECK-NEXT:    ret i1 false1152;1153  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1154  %cmp = icmp eq i32 %t0, 11155  %notzero = icmp eq i32 %x, 01156  %r = and i1 %notzero, %cmp1157  ret i1 %r1158}1159 1160define i1 @isnot_pow2nor0_ctpop_wrong_pred2_logical(i32 %x) {1161; CHECK-LABEL: @isnot_pow2nor0_ctpop_wrong_pred2_logical(1162; CHECK-NEXT:    ret i1 false1163;1164  %t0 = tail call i32 @llvm.ctpop.i32(i32 %x)1165  %cmp = icmp eq i32 %t0, 11166  %notzero = icmp eq i32 %x, 01167  %r = select i1 %notzero, i1 %cmp, i1 false1168  ret i1 %r1169}1170 1171define <2 x i1> @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(<2 x i8> %x) {1172; CHECK-LABEL: @isnot_pow2nor0_wrong_pred3_ctpop_commute_vec(1173; CHECK-NEXT:    ret <2 x i1> splat (i1 true)1174;1175  %t0 = tail call <2 x i8> @llvm.ctpop.v2i8(<2 x i8> %x)1176  %cmp = icmp ne <2 x i8> %t0, <i8 1, i8 1>1177  %notzero = icmp ne <2 x i8> %x, <i8 0, i8 0>1178  %r = or <2 x i1> %cmp, %notzero1179  ret <2 x i1> %r1180}1181 1182define i1 @is_pow2_fail_pr63327(i32 %x) {1183; CHECK-LABEL: @is_pow2_fail_pr63327(1184; CHECK-NEXT:    [[NX:%.*]] = sub i32 0, [[X:%.*]]1185; CHECK-NEXT:    [[X_AND_NX:%.*]] = and i32 [[X]], [[NX]]1186; CHECK-NEXT:    [[R:%.*]] = icmp sge i32 [[X_AND_NX]], [[X]]1187; CHECK-NEXT:    ret i1 [[R]]1188;1189  %nx = sub i32 0, %x1190  %x_and_nx = and i32 %x, %nx1191  %r = icmp sge i32 %x_and_nx, %x1192  ret i1 %r1193}1194 1195define i1 @blsmsk_is_p2_or_z(i32 %xx, i32 %yy) {1196; CHECK-LABEL: @blsmsk_is_p2_or_z(1197; CHECK-NEXT:    [[X:%.*]] = or i32 [[XX:%.*]], [[YY:%.*]]1198; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X]], -11199; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]1200; CHECK-NEXT:    [[R:%.*]] = icmp uge i32 [[X]], [[Y]]1201; CHECK-NEXT:    ret i1 [[R]]1202;1203  %x = or i32 %xx, %yy1204  %xm1 = add i32 %x, -11205  %y = xor i32 %x, %xm11206  %r = icmp uge i32 %x, %y1207  ret i1 %r1208}1209 1210define i1 @blsmsk_isnt_p2_or_z(i32 %x) {1211; CHECK-LABEL: @blsmsk_isnt_p2_or_z(1212; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1213; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[TMP1]], 11214; CHECK-NEXT:    ret i1 [[R]]1215;1216  %xm1 = add i32 %x, -11217  %y = xor i32 %x, %xm11218  %r = icmp ult i32 %y, %x1219  ret i1 %r1220}1221 1222define i1 @blsmsk_is_p2_or_z_fail(i32 %xx, i32 %yy) {1223; CHECK-LABEL: @blsmsk_is_p2_or_z_fail(1224; CHECK-NEXT:    [[X:%.*]] = or i32 [[XX:%.*]], [[YY:%.*]]1225; CHECK-NEXT:    [[TMP1:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X]])1226; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i32 [[TMP1]], 11227; CHECK-NEXT:    ret i1 [[R]]1228;1229  %x = or i32 %xx, %yy1230  %xm1 = add i32 %x, -11231  %y = xor i32 %x, %xm11232  %r = icmp ugt i32 %x, %y1233  ret i1 %r1234}1235 1236define i1 @blsmsk_isnt_p2_or_z_fail(i32 %x) {1237; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail(1238; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -11239; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]1240; CHECK-NEXT:    [[R:%.*]] = icmp ule i32 [[Y]], [[X]]1241; CHECK-NEXT:    ret i1 [[R]]1242;1243  %xm1 = add i32 %x, -11244  %y = xor i32 %x, %xm11245  %r = icmp ule i32 %y, %x1246  ret i1 %r1247}1248 1249declare void @use.i32(i32)1250 1251define i1 @blsmsk_isnt_p2_or_z_fail_multiuse(i32 %x) {1252; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail_multiuse(1253; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -11254; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]1255; CHECK-NEXT:    call void @use.i32(i32 [[Y]])1256; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y]], [[X]]1257; CHECK-NEXT:    ret i1 [[R]]1258;1259  %xm1 = add i32 %x, -11260  %y = xor i32 %x, %xm11261  call void @use.i32(i32 %y)1262  %r = icmp ult i32 %y, %x1263  ret i1 %r1264}1265 1266define i1 @blsmsk_isnt_p2_or_z_fail_wrong_add(i32 %x, i32 %z) {1267; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail_wrong_add(1268; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[Z:%.*]], -11269; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X:%.*]], [[XM1]]1270; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y]], [[X]]1271; CHECK-NEXT:    ret i1 [[R]]1272;1273  %xm1 = add i32 %z, -11274  %y = xor i32 %x, %xm11275  %r = icmp ult i32 %y, %x1276  ret i1 %r1277}1278 1279 1280define i1 @blsmsk_isnt_p2_or_z_fail_bad_xor(i32 %x, i32 %z) {1281; CHECK-LABEL: @blsmsk_isnt_p2_or_z_fail_bad_xor(1282; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -11283; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[Z:%.*]], [[XM1]]1284; CHECK-NEXT:    [[R:%.*]] = icmp ult i32 [[Y]], [[X]]1285; CHECK-NEXT:    ret i1 [[R]]1286;1287  %xm1 = add i32 %x, -11288  %y = xor i32 %z, %xm11289  %r = icmp ult i32 %y, %x1290  ret i1 %r1291}1292 1293 1294define i1 @blsmsk_is_p2_or_z_fail_bad_cmp(i32 %x, i32 %z) {1295; CHECK-LABEL: @blsmsk_is_p2_or_z_fail_bad_cmp(1296; CHECK-NEXT:    [[XM1:%.*]] = add i32 [[X:%.*]], -11297; CHECK-NEXT:    [[Y:%.*]] = xor i32 [[X]], [[XM1]]1298; CHECK-NEXT:    [[R:%.*]] = icmp uge i32 [[Y]], [[Z:%.*]]1299; CHECK-NEXT:    ret i1 [[R]]1300;1301  %xm1 = add i32 %x, -11302  %y = xor i32 %x, %xm11303  %r = icmp uge i32 %y, %z1304  ret i1 %r1305}1306 1307define i1 @blsmsk_is_p2_or_z_ule_xy(i8 %xx, i8 %yy) {1308; CHECK-LABEL: @blsmsk_is_p2_or_z_ule_xy(1309; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1310; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])1311; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i8 [[TMP1]], 21312; CHECK-NEXT:    ret i1 [[R]]1313;1314  %x = or i8 %xx, %yy1315  %xm1 = add i8 %x, -11316  %y = xor i8 %x, %xm11317  %r = icmp ule i8 %x, %y1318  ret i1 %r1319}1320 1321 1322define i1 @blsmsk_is_p2_or_z_ule_yx_fail(i8 %xx, i8 %yy) {1323; CHECK-LABEL: @blsmsk_is_p2_or_z_ule_yx_fail(1324; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1325; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -11326; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]1327; CHECK-NEXT:    [[R:%.*]] = icmp ule i8 [[Y]], [[X]]1328; CHECK-NEXT:    ret i1 [[R]]1329;1330  %x = or i8 %xx, %yy1331  %xm1 = add i8 %x, -11332  %y = xor i8 %x, %xm11333  %r = icmp ule i8 %y, %x1334  ret i1 %r1335}1336 1337 1338define i1 @blsmsk_is_p2_or_z_uge_yx(i8 %xx, i8 %yy) {1339; CHECK-LABEL: @blsmsk_is_p2_or_z_uge_yx(1340; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1341; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])1342; CHECK-NEXT:    [[R:%.*]] = icmp samesign ult i8 [[TMP1]], 21343; CHECK-NEXT:    ret i1 [[R]]1344;1345  %x = or i8 %xx, %yy1346  %xm1 = add i8 %x, -11347  %y = xor i8 %x, %xm11348  %r = icmp uge i8 %y, %x1349  ret i1 %r1350}1351 1352 1353define i1 @blsmsk_is_p2_or_z_uge_xy_fail(i8 %xx, i8 %yy) {1354; CHECK-LABEL: @blsmsk_is_p2_or_z_uge_xy_fail(1355; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1356; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -11357; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]1358; CHECK-NEXT:    [[R:%.*]] = icmp uge i8 [[X]], [[Y]]1359; CHECK-NEXT:    ret i1 [[R]]1360;1361  %x = or i8 %xx, %yy1362  %xm1 = add i8 %x, -11363  %y = xor i8 %x, %xm11364  %r = icmp uge i8 %x, %y1365  ret i1 %r1366}1367 1368define i1 @blsmsk_isnt_p2_or_z_ugt_xy(i8 %xx, i8 %yy) {1369; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ugt_xy(1370; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1371; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])1372; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i8 [[TMP1]], 11373; CHECK-NEXT:    ret i1 [[R]]1374;1375  %x = or i8 %xx, %yy1376  %xm1 = add i8 %x, -11377  %y = xor i8 %x, %xm11378  %r = icmp ugt i8 %x, %y1379  ret i1 %r1380}1381 1382 1383define i1 @blsmsk_isnt_p2_or_z_ugt_yx_fail(i8 %xx, i8 %yy) {1384; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ugt_yx_fail(1385; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1386; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -11387; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]1388; CHECK-NEXT:    [[R:%.*]] = icmp ugt i8 [[Y]], [[X]]1389; CHECK-NEXT:    ret i1 [[R]]1390;1391  %x = or i8 %xx, %yy1392  %xm1 = add i8 %x, -11393  %y = xor i8 %x, %xm11394  %r = icmp ugt i8 %y, %x1395  ret i1 %r1396}1397 1398 1399define i1 @blsmsk_isnt_p2_or_z_ult_yx(i8 %xx, i8 %yy) {1400; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ult_yx(1401; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1402; CHECK-NEXT:    [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.ctpop.i8(i8 [[X]])1403; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt i8 [[TMP1]], 11404; CHECK-NEXT:    ret i1 [[R]]1405;1406  %x = or i8 %xx, %yy1407  %xm1 = add i8 %x, -11408  %y = xor i8 %x, %xm11409  %r = icmp ult i8 %y, %x1410  ret i1 %r1411}1412 1413 1414define i1 @blsmsk_isnt_p2_or_z_ult_xy_fail(i8 %xx, i8 %yy) {1415; CHECK-LABEL: @blsmsk_isnt_p2_or_z_ult_xy_fail(1416; CHECK-NEXT:    [[X:%.*]] = or i8 [[XX:%.*]], [[YY:%.*]]1417; CHECK-NEXT:    [[XM1:%.*]] = add i8 [[X]], -11418; CHECK-NEXT:    [[Y:%.*]] = xor i8 [[X]], [[XM1]]1419; CHECK-NEXT:    [[R:%.*]] = icmp ult i8 [[X]], [[Y]]1420; CHECK-NEXT:    ret i1 [[R]]1421;1422  %x = or i8 %xx, %yy1423  %xm1 = add i8 %x, -11424  %y = xor i8 %x, %xm11425  %r = icmp ult i8 %x, %y1426  ret i1 %r1427}1428 1429declare <2 x i32> @llvm.ctpop.2xi32(<2 x i32>)1430define i1 @is_pow2_nz_known_bits(i32 %xin) {1431; CHECK-LABEL: @is_pow2_nz_known_bits(1432; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[XIN:%.*]], -651433; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 01434; CHECK-NEXT:    ret i1 [[R]]1435;1436  %x = or i32 %xin, 641437  %cnt = call i32 @llvm.ctpop.i32(i32 %x)1438  %r = icmp eq i32 %cnt, 11439  ret i1 %r1440}1441 1442define i1 @is_pow2_nz_known_bits_fail_multiuse(i32 %xin) {1443; CHECK-LABEL: @is_pow2_nz_known_bits_fail_multiuse(1444; CHECK-NEXT:    [[X:%.*]] = or i32 [[XIN:%.*]], 641445; CHECK-NEXT:    [[CNT:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])1446; CHECK-NEXT:    call void @use.i32(i32 [[CNT]])1447; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[CNT]], 11448; CHECK-NEXT:    ret i1 [[R]]1449;1450  %x = or i32 %xin, 641451  %cnt = call i32 @llvm.ctpop.i32(i32 %x)1452  call void @use.i32(i32 %cnt)1453  %r = icmp eq i32 %cnt, 11454  ret i1 %r1455}1456 1457define i1 @not_pow2_nz_known_bits(i32 %xin) {1458; CHECK-LABEL: @not_pow2_nz_known_bits(1459; CHECK-NEXT:    [[R:%.*]] = icmp ugt i32 [[XIN:%.*]], 11460; CHECK-NEXT:    ret i1 [[R]]1461;1462  %x = or i32 %xin, 11463  %cnt = call i32 @llvm.ctpop.i32(i32 %x)1464  %r = icmp ne i32 %cnt, 11465  ret i1 %r1466}1467 1468define i1 @not_pow2_nz_known_bits_fail_not_p2_test(i32 %xin) {1469; CHECK-LABEL: @not_pow2_nz_known_bits_fail_not_p2_test(1470; CHECK-NEXT:    [[X:%.*]] = or i32 [[XIN:%.*]], 11471; CHECK-NEXT:    [[CNT:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[X]])1472; CHECK-NEXT:    [[R:%.*]] = icmp ne i32 [[CNT]], 21473; CHECK-NEXT:    ret i1 [[R]]1474;1475  %x = or i32 %xin, 11476  %cnt = call i32 @llvm.ctpop.i32(i32 %x)1477  %r = icmp ne i32 %cnt, 21478  ret i1 %r1479}1480 1481define i1 @is_pow2_or_z_known_bits(i32 %xin) {1482; CHECK-LABEL: @is_pow2_or_z_known_bits(1483; CHECK-NEXT:    [[TMP1:%.*]] = and i32 [[XIN:%.*]], 21474836471484; CHECK-NEXT:    [[R:%.*]] = icmp eq i32 [[TMP1]], 01485; CHECK-NEXT:    ret i1 [[R]]1486;1487  %x = or i32 %xin, 21474836481488  %cnt = call i32 @llvm.ctpop.i32(i32 %x)1489  %r = icmp ult i32 %cnt, 21490  ret i1 %r1491}1492 1493define <2 x i1> @not_pow2_or_z_known_bits(<2 x i32> %xin) {1494; CHECK-LABEL: @not_pow2_or_z_known_bits(1495; CHECK-NEXT:    [[TMP1:%.*]] = and <2 x i32> [[XIN:%.*]], splat (i32 -65)1496; CHECK-NEXT:    [[R:%.*]] = icmp ne <2 x i32> [[TMP1]], zeroinitializer1497; CHECK-NEXT:    ret <2 x i1> [[R]]1498;1499  %x = or <2 x i32> %xin, <i32 64, i32 64>1500  %cnt = call <2 x i32> @llvm.ctpop.2xi32(<2 x i32> %x)1501  %r = icmp ugt <2 x i32> %cnt, <i32 1, i32 1>1502  ret <2 x i1> %r1503}1504 1505define <2 x i1> @not_pow2_or_z_known_bits_fail_wrong_cmp(<2 x i32> %xin) {1506; CHECK-LABEL: @not_pow2_or_z_known_bits_fail_wrong_cmp(1507; CHECK-NEXT:    [[X:%.*]] = or <2 x i32> [[XIN:%.*]], splat (i32 64)1508; CHECK-NEXT:    [[CNT:%.*]] = call range(i32 1, 33) <2 x i32> @llvm.ctpop.v2i32(<2 x i32> [[X]])1509; CHECK-NEXT:    [[R:%.*]] = icmp samesign ugt <2 x i32> [[CNT]], splat (i32 2)1510; CHECK-NEXT:    ret <2 x i1> [[R]]1511;1512  %x = or <2 x i32> %xin, <i32 64, i32 64>1513  %cnt = call <2 x i32> @llvm.ctpop.2xi32(<2 x i32> %x)1514  %r = icmp ugt <2 x i32> %cnt, <i32 2, i32 2>1515  ret <2 x i1> %r1516}1517 1518; Make sure that range attributes on return values are dropped after merging these two icmps1519 1520define i1 @has_single_bit(i32 %x) {1521; CHECK-LABEL: @has_single_bit(1522; CHECK-NEXT:  entry:1523; CHECK-NEXT:    [[POPCNT:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1524; CHECK-NEXT:    [[SEL:%.*]] = icmp eq i32 [[POPCNT]], 11525; CHECK-NEXT:    ret i1 [[SEL]]1526;1527entry:1528  %cmp1 = icmp ne i32 %x, 01529  %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)1530  %cmp2 = icmp ult i32 %popcnt, 21531  %sel = select i1 %cmp1, i1 %cmp2, i1 false1532  ret i1 %sel1533}1534 1535define i1 @has_single_bit_inv(i32 %x) {1536; CHECK-LABEL: @has_single_bit_inv(1537; CHECK-NEXT:  entry:1538; CHECK-NEXT:    [[POPCNT:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1539; CHECK-NEXT:    [[SEL:%.*]] = icmp ne i32 [[POPCNT]], 11540; CHECK-NEXT:    ret i1 [[SEL]]1541;1542entry:1543  %cmp1 = icmp eq i32 %x, 01544  %popcnt = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)1545  %cmp2 = icmp ugt i32 %popcnt, 11546  %sel = select i1 %cmp1, i1 true, i1 %cmp21547  ret i1 %sel1548}1549 1550define i1 @is_power2_or_zero_with_range(i32 %x) {1551; CHECK-LABEL: @is_power2_or_zero_with_range(1552; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1553; CHECK-NEXT:    [[RES:%.*]] = icmp samesign ult i32 [[CTPOP]], 21554; CHECK-NEXT:    ret i1 [[RES]]1555;1556  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)1557  %cmp = icmp eq i32 %ctpop, 11558  %notzero = icmp eq i32 %x, 01559  %res = select i1 %notzero, i1 true, i1 %cmp1560  ret i1 %res1561}1562 1563define i1 @is_power2_or_zero_inv_with_range(i32 %x) {1564; CHECK-LABEL: @is_power2_or_zero_inv_with_range(1565; CHECK-NEXT:    [[CTPOP:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[X:%.*]])1566; CHECK-NEXT:    [[RES:%.*]] = icmp samesign ugt i32 [[CTPOP]], 11567; CHECK-NEXT:    ret i1 [[RES]]1568;1569  %ctpop = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 %x)1570  %cmp = icmp ne i32 %ctpop, 11571  %notzero = icmp ne i32 %x, 01572  %res = select i1 %notzero, i1 %cmp, i1 false1573  ret i1 %res1574}1575