146 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 62; RUN: opt < %s -S -passes=instcombine | FileCheck %s3 4; ctpop(~i & (i - 1)) -> bitwidth - cttz(i, false)5define i8 @ctlz_to_sub_bw_cttz(i8 %a0) {6; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz(7; CHECK-SAME: i8 [[A0:%.*]]) {8; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[A0]], i1 false)9; CHECK-NEXT: [[CLZ:%.*]] = sub nuw nsw i8 8, [[TMP1]]10; CHECK-NEXT: ret i8 [[CLZ]]11;12 %dec = add i8 %a0, -113 %not = xor i8 %a0, -114 %and = and i8 %dec, %not15 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)16 ret i8 %clz17}18 19define i8 @ctlz_to_sub_bw_cttz_poison(i8 %a0) {20; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_poison(21; CHECK-SAME: i8 [[A0:%.*]]) {22; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[A0]], i1 false)23; CHECK-NEXT: [[CLZ:%.*]] = sub nuw nsw i8 8, [[TMP1]]24; CHECK-NEXT: ret i8 [[CLZ]]25;26 %dec = add i8 %a0, -127 %not = xor i8 %a0, -128 %and = and i8 %dec, %not29 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 true)30 ret i8 %clz31}32 33define i8 @ctlz_to_sub_bw_cttz_different_add(i8 %a0) {34; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_different_add(35; CHECK-SAME: i8 [[A0:%.*]]) {36; CHECK-NEXT: [[DEC:%.*]] = add i8 [[A0]], 137; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A0]], -138; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[NOT]]39; CHECK-NEXT: [[CLZ:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[AND]], i1 false)40; CHECK-NEXT: ret i8 [[CLZ]]41;42 %dec = add i8 %a0, 143 %not = xor i8 %a0, -144 %and = and i8 %dec, %not45 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)46 ret i8 %clz47}48 49define i8 @ctlz_to_sub_bw_cttz_different_xor(i8 %a0) {50; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_different_xor(51; CHECK-SAME: i8 [[A0:%.*]]) {52; CHECK-NEXT: [[DEC:%.*]] = add i8 [[A0]], -153; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A0]], 154; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[NOT]]55; CHECK-NEXT: [[CLZ:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[AND]], i1 false)56; CHECK-NEXT: ret i8 [[CLZ]]57;58 %dec = add i8 %a0, -159 %not = xor i8 %a0, 160 %and = and i8 %dec, %not61 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)62 ret i8 %clz63}64 65declare void @use(i8)66 67define i8 @ctlz_to_sub_bw_cttz_multi_use_dec(i8 %a0) {68; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_multi_use_dec(69; CHECK-SAME: i8 [[A0:%.*]]) {70; CHECK-NEXT: [[DEC:%.*]] = add i8 [[A0]], -171; CHECK-NEXT: call void @use(i8 [[DEC]])72; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[A0]], i1 false)73; CHECK-NEXT: [[CLZ:%.*]] = sub nuw nsw i8 8, [[TMP1]]74; CHECK-NEXT: ret i8 [[CLZ]]75;76 %dec = add i8 %a0, -177 call void @use(i8 %dec)78 %not = xor i8 %a0, -179 %and = and i8 %dec, %not80 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)81 ret i8 %clz82}83 84define i8 @ctlz_to_sub_bw_cttz_multi_use_not(i8 %a0) {85; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_multi_use_not(86; CHECK-SAME: i8 [[A0:%.*]]) {87; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A0]], -188; CHECK-NEXT: call void @use(i8 [[NOT]])89; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[A0]], i1 false)90; CHECK-NEXT: [[CLZ:%.*]] = sub nuw nsw i8 8, [[TMP1]]91; CHECK-NEXT: ret i8 [[CLZ]]92;93 %dec = add i8 %a0, -194 %not = xor i8 %a0, -195 call void @use(i8 %not)96 %and = and i8 %dec, %not97 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)98 ret i8 %clz99}100 101define i8 @ctlz_to_sub_bw_cttz_multi_use_and(i8 %a0) {102; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_multi_use_and(103; CHECK-SAME: i8 [[A0:%.*]]) {104; CHECK-NEXT: [[DEC:%.*]] = add i8 [[A0]], -1105; CHECK-NEXT: [[NOT:%.*]] = xor i8 [[A0]], -1106; CHECK-NEXT: [[AND:%.*]] = and i8 [[DEC]], [[NOT]]107; CHECK-NEXT: call void @use(i8 [[AND]])108; CHECK-NEXT: [[CLZ:%.*]] = tail call range(i8 0, 9) i8 @llvm.ctlz.i8(i8 [[AND]], i1 false)109; CHECK-NEXT: ret i8 [[CLZ]]110;111 %dec = add i8 %a0, -1112 %not = xor i8 %a0, -1113 %and = and i8 %dec, %not114 call void @use(i8 %and)115 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)116 ret i8 %clz117}118 119define i8 @ctlz_to_sub_bw_cttz_commute_and(i8 %a0) {120; CHECK-LABEL: define i8 @ctlz_to_sub_bw_cttz_commute_and(121; CHECK-SAME: i8 [[A0:%.*]]) {122; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) i8 @llvm.cttz.i8(i8 [[A0]], i1 false)123; CHECK-NEXT: [[CLZ:%.*]] = sub nuw nsw i8 8, [[TMP1]]124; CHECK-NEXT: ret i8 [[CLZ]]125;126 %dec = add i8 %a0, -1127 %not = xor i8 %a0, -1128 %and = and i8 %not, %dec129 %clz = tail call i8 @llvm.ctlz.i8(i8 %and, i1 false)130 ret i8 %clz131}132 133define <2 x i8> @ctlz_to_sub_bw_cttz_vec_splat(<2 x i8> %a0) {134; CHECK-LABEL: define <2 x i8> @ctlz_to_sub_bw_cttz_vec_splat(135; CHECK-SAME: <2 x i8> [[A0:%.*]]) {136; CHECK-NEXT: [[TMP1:%.*]] = call range(i8 0, 9) <2 x i8> @llvm.cttz.v2i8(<2 x i8> [[A0]], i1 false)137; CHECK-NEXT: [[CLZ:%.*]] = sub nuw nsw <2 x i8> splat (i8 8), [[TMP1]]138; CHECK-NEXT: ret <2 x i8> [[CLZ]]139;140 %dec = add <2 x i8> %a0, <i8 -1, i8 -1>141 %not = xor <2 x i8> %a0, <i8 -1, i8 -1>142 %and = and <2 x i8> %dec, %not143 %clz = tail call <2 x i8>@llvm.ctlz.v2i8(<2 x i8> %and, i1 false)144 ret <2 x i8> %clz145}146