151 lines · plain
1; NOTE: Assertions have been autogenerated by utils/update_test_checks.py2; RUN: opt < %s -S -passes=instcombine | FileCheck %s3 4declare i32 @llvm.ctpop.i32(i32)5declare <2 x i32> @llvm.ctpop.v2i32(<2 x i32>)6 7; PR435138; __builtin_popcount(i | -i) -> 32 - __builtin_cttz(i, false)9define i32 @ctpop1(i32 %0) {10; CHECK-LABEL: @ctpop1(11; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP0:%.*]], i1 false)12; CHECK-NEXT: ret i32 [[TMP2]]13;14 %2 = sub i32 0, %015 %3 = or i32 %0, %216 %4 = tail call i32 @llvm.ctpop.i32(i32 %3)17 %5 = sub i32 32, %418 ret i32 %519}20 21define <2 x i32> @ctpop1v(<2 x i32> %0) {22; CHECK-LABEL: @ctpop1v(23; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[TMP0:%.*]], i1 false)24; CHECK-NEXT: [[TMP3:%.*]] = sub nuw nsw <2 x i32> splat (i32 32), [[TMP2]]25; CHECK-NEXT: ret <2 x i32> [[TMP3]]26;27 %2 = sub <2 x i32> zeroinitializer, %028 %3 = or <2 x i32> %2, %029 %4 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %3)30 ret <2 x i32> %431}32 33define i32 @ctpop1_multiuse(i32 %0) {34; CHECK-LABEL: @ctpop1_multiuse(35; CHECK-NEXT: [[TMP2:%.*]] = sub i32 0, [[TMP0:%.*]]36; CHECK-NEXT: [[TMP3:%.*]] = or i32 [[TMP0]], [[TMP2]]37; CHECK-NEXT: [[TMP4:%.*]] = xor i32 [[TMP3]], -138; CHECK-NEXT: [[TMP5:%.*]] = call range(i32 0, 33) i32 @llvm.ctpop.i32(i32 [[TMP4]])39; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], [[TMP3]]40; CHECK-NEXT: ret i32 [[TMP6]]41;42 %2 = sub i32 0, %043 %3 = or i32 %0, %244 %4 = tail call i32 @llvm.ctpop.i32(i32 %3)45 %5 = sub i32 32, %446 %6 = add i32 %5, %347 ret i32 %648}49 50; PR4351351; __builtin_popcount(~i & (i-1)) -> __builtin_cttz(i, false)52define i32 @ctpop2(i32 %0) {53; CHECK-LABEL: @ctpop2(54; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP0:%.*]], i1 false)55; CHECK-NEXT: ret i32 [[TMP2]]56;57 %2 = xor i32 %0, -158 %3 = sub i32 %0, 159 %4 = and i32 %3, %260 %5 = tail call i32 @llvm.ctpop.i32(i32 %4)61 ret i32 %562}63 64define <2 x i32> @ctpop2v(<2 x i32> %0) {65; CHECK-LABEL: @ctpop2v(66; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[TMP0:%.*]], i1 false)67; CHECK-NEXT: ret <2 x i32> [[TMP2]]68;69 %2 = xor <2 x i32> %0, <i32 -1, i32 -1>70 %3 = add <2 x i32> %0, <i32 -1, i32 -1>71 %4 = and <2 x i32> %2, %372 %5 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %4)73 ret <2 x i32> %574}75 76define i32 @ctpop2_multiuse(i32 %0) {77; CHECK-LABEL: @ctpop2_multiuse(78; CHECK-NEXT: [[TMP2:%.*]] = xor i32 [[TMP0:%.*]], -179; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP0]], -180; CHECK-NEXT: [[TMP4:%.*]] = and i32 [[TMP3]], [[TMP2]]81; CHECK-NEXT: [[TMP5:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP0]], i1 false)82; CHECK-NEXT: [[TMP6:%.*]] = add i32 [[TMP5]], [[TMP4]]83; CHECK-NEXT: ret i32 [[TMP6]]84;85 %2 = xor i32 %0, -186 %3 = sub i32 %0, 187 %4 = and i32 %3, %288 %5 = tail call i32 @llvm.ctpop.i32(i32 %4)89 %6 = add i32 %5, %490 ret i32 %691}92 93; PR5178494; __builtin_popcount((i & -i) - 1) -> __builtin_cttz(i, false)95define i32 @ctpop3(i32 %0) {96; CHECK-LABEL: @ctpop3(97; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) i32 @llvm.cttz.i32(i32 [[TMP0:%.*]], i1 false)98; CHECK-NEXT: ret i32 [[TMP2]]99;100 %2 = sub i32 0, %0101 %3 = and i32 %2, %0102 %4 = add i32 %3, -1103 %5 = tail call i32 @llvm.ctpop.i32(i32 %4)104 ret i32 %5105}106 107define <2 x i32> @ctpop3v(<2 x i32> %0) {108; CHECK-LABEL: @ctpop3v(109; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[TMP0:%.*]], i1 false)110; CHECK-NEXT: ret <2 x i32> [[TMP2]]111;112 %2 = sub <2 x i32> zeroinitializer, %0113 %3 = and <2 x i32> %2, %0114 %4 = add <2 x i32> %3, <i32 -1, i32 -1>115 %5 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %4)116 ret <2 x i32> %5117}118 119define <2 x i32> @ctpop3v_poison(<2 x i32> %0) {120; CHECK-LABEL: @ctpop3v_poison(121; CHECK-NEXT: [[TMP2:%.*]] = call range(i32 0, 33) <2 x i32> @llvm.cttz.v2i32(<2 x i32> [[TMP0:%.*]], i1 false)122; CHECK-NEXT: ret <2 x i32> [[TMP2]]123;124 %2 = sub <2 x i32> zeroinitializer, %0125 %3 = and <2 x i32> %2, %0126 %4 = add <2 x i32> %3, <i32 -1, i32 poison>127 %5 = tail call <2 x i32> @llvm.ctpop.v2i32(<2 x i32> %4)128 ret <2 x i32> %5129}130 131define i32 @ctpop_xor(i32 %x, i32 %y) {132; CHECK-LABEL: @ctpop_xor(133; CHECK-NEXT: [[CMP_NOT:%.*]] = icmp eq i32 [[X:%.*]], [[Y:%.*]]134; CHECK-NEXT: br i1 [[CMP_NOT]], label [[FALSE:%.*]], label [[TRUE:%.*]]135; CHECK: true:136; CHECK-NEXT: [[XOR:%.*]] = xor i32 [[X]], [[Y]]137; CHECK-NEXT: [[RET:%.*]] = call range(i32 1, 33) i32 @llvm.ctpop.i32(i32 [[XOR]])138; CHECK-NEXT: ret i32 [[RET]]139; CHECK: false:140; CHECK-NEXT: ret i32 0141;142 %cmp = icmp ne i32 %x, %y143 br i1 %cmp, label %true, label %false144true:145 %xor = xor i32 %x, %y146 %ret = call i32 @llvm.ctpop.i32(i32 %xor)147 ret i32 %ret148false:149 ret i32 0150}151