Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineCalls.cpp @@ -1383,6 +1383,14 @@ assert(II.getIntrinsicID() == Intrinsic::ctpop && "Expected ctpop intrinsic"); Value *Op0 = II.getArgOperand(0); + Value *X; + // ctpop(bitreverse(x)) -> ctpop(x) + // ctpop(bswap(x)) -> ctpop(x) + if (match(Op0, m_BitReverse(m_Value(X))) || match(Op0, m_BSwap(m_Value(X)))) { + II.setOperand(0, X); + return &II; + } + // FIXME: Try to simplify vectors of integers. auto *IT = dyn_cast(Op0->getType()); if (!IT) Index: llvm/trunk/test/Transforms/InstCombine/ctpop-bswap-bitreverse.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/ctpop-bswap-bitreverse.ll +++ llvm/trunk/test/Transforms/InstCombine/ctpop-bswap-bitreverse.ll @@ -3,8 +3,7 @@ define i32 @ctpop_bitreverse(i32 %x) { ; CHECK-LABEL: @ctpop_bitreverse( -; CHECK-NEXT: [[A:%.*]] = tail call i32 @llvm.bitreverse.i32(i32 [[X:%.*]]) -; CHECK-NEXT: [[B:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[A]]), !range !0 +; CHECK-NEXT: [[B:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0 ; CHECK-NEXT: ret i32 [[B]] ; %a = tail call i32 @llvm.bitreverse.i32(i32 %x) @@ -14,8 +13,7 @@ define <2 x i64> @ctpop_bitreverse_vec(<2 x i64> %x) { ; CHECK-LABEL: @ctpop_bitreverse_vec( -; CHECK-NEXT: [[A:%.*]] = tail call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> [[X:%.*]]) -; CHECK-NEXT: [[B:%.*]] = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[A]]) +; CHECK-NEXT: [[B:%.*]] = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[X:%.*]]) ; CHECK-NEXT: ret <2 x i64> [[B]] ; %a = tail call <2 x i64> @llvm.bitreverse.v2i64(<2 x i64> %x) @@ -25,8 +23,7 @@ define i32 @ctpop_bswap(i32 %x) { ; CHECK-LABEL: @ctpop_bswap( -; CHECK-NEXT: [[A:%.*]] = tail call i32 @llvm.bswap.i32(i32 [[X:%.*]]) -; CHECK-NEXT: [[B:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[A]]), !range !0 +; CHECK-NEXT: [[B:%.*]] = tail call i32 @llvm.ctpop.i32(i32 [[X:%.*]]), !range !0 ; CHECK-NEXT: ret i32 [[B]] ; %a = tail call i32 @llvm.bswap.i32(i32 %x) @@ -36,8 +33,7 @@ define <2 x i64> @ctpop_bswap_vec(<2 x i64> %x) { ; CHECK-LABEL: @ctpop_bswap_vec( -; CHECK-NEXT: [[A:%.*]] = tail call <2 x i64> @llvm.bswap.v2i64(<2 x i64> [[X:%.*]]) -; CHECK-NEXT: [[B:%.*]] = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[A]]) +; CHECK-NEXT: [[B:%.*]] = tail call <2 x i64> @llvm.ctpop.v2i64(<2 x i64> [[X:%.*]]) ; CHECK-NEXT: ret <2 x i64> [[B]] ; %a = tail call <2 x i64> @llvm.bswap.v2i64(<2 x i64> %x)