Index: llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp =================================================================== --- llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineAndOrXor.cpp @@ -82,20 +82,25 @@ Value *InstCombiner::SimplifyBSwap(BinaryOperator &I) { assert(I.isBitwiseLogicOp() && "Unexpected opcode for bswap simplifying"); - // TODO We should probably check for single use of the bswap. + Value *OldLHS = I.getOperand(0); + Value *OldRHS = I.getOperand(1); Value *NewLHS; - if (!match(I.getOperand(0), m_BSwap(m_Value(NewLHS)))) + if (!match(OldLHS, m_BSwap(m_Value(NewLHS)))) return nullptr; Value *NewRHS; const APInt *C; - if (match(I.getOperand(1), m_BSwap(m_Value(NewRHS)))) { + if (match(OldRHS, m_BSwap(m_Value(NewRHS)))) { // OP( BSWAP(x), BSWAP(y) ) -> BSWAP( OP(x, y) ) + if (!OldLHS->hasOneUse() && !OldRHS->hasOneUse()) + return nullptr; // NewRHS initialized by the matcher. - } else if (match(I.getOperand(1), m_APInt(C))) { + } else if (match(OldRHS, m_APInt(C))) { // OP( BSWAP(x), CONSTANT ) -> BSWAP( OP(x, BSWAP(CONSTANT) ) ) + if (!OldLHS->hasOneUse()) + return nullptr; NewRHS = ConstantInt::get(I.getType(), C->byteSwap()); } else return nullptr; Index: llvm/trunk/test/Transforms/InstCombine/bswap-fold.ll =================================================================== --- llvm/trunk/test/Transforms/InstCombine/bswap-fold.ll +++ llvm/trunk/test/Transforms/InstCombine/bswap-fold.ll @@ -285,9 +285,8 @@ ; CHECK-LABEL: @bs_and64_multiuse1( ; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bswap.i64(i64 [[A:%.*]]) ; CHECK-NEXT: [[TMP2:%.*]] = tail call i64 @llvm.bswap.i64(i64 [[B:%.*]]) -; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[A]], [[B]] -; CHECK-NEXT: [[TMP6:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP3]]) -; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP6]], [[TMP1]] +; CHECK-NEXT: [[TMP3:%.*]] = and i64 [[TMP1]], [[TMP2]] +; CHECK-NEXT: [[TMP4:%.*]] = mul i64 [[TMP3]], [[TMP1]] ; CHECK-NEXT: [[TMP5:%.*]] = mul i64 [[TMP4]], [[TMP2]] ; CHECK-NEXT: ret i64 [[TMP5]] ; @@ -332,9 +331,8 @@ define i64 @bs_and64i_multiuse(i64 %a, i64 %b) #0 { ; CHECK-LABEL: @bs_and64i_multiuse( ; CHECK-NEXT: [[TMP1:%.*]] = tail call i64 @llvm.bswap.i64(i64 [[A:%.*]]) -; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[A]], 129085117527228416 -; CHECK-NEXT: [[TMP4:%.*]] = call i64 @llvm.bswap.i64(i64 [[TMP2]]) -; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP4]], [[TMP1]] +; CHECK-NEXT: [[TMP2:%.*]] = and i64 [[TMP1]], 1000000001 +; CHECK-NEXT: [[TMP3:%.*]] = mul i64 [[TMP2]], [[TMP1]] ; CHECK-NEXT: ret i64 [[TMP3]] ; %tmp1 = tail call i64 @llvm.bswap.i64(i64 %a)