diff --git a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp --- a/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp +++ b/llvm/lib/Transforms/InstCombine/InstCombineAddSub.cpp @@ -972,7 +972,7 @@ // If all bits affected by the add are included in a high-bit-mask, do the // add before the mask op: // (X & 0xFF00) + xx00 --> (X + xx00) & 0xFF00 - if (match(Op0, m_OneUse(m_And(m_Value(X), m_APInt(C2)))) && + if (match(Op0, m_OneUse(m_And(m_OneUse(m_Value(X)), m_APInt(C2)))) && C2->isNegative() && C2->isShiftedMask() && *C == (*C & *C2)) { Value *NewAdd = Builder.CreateAdd(X, ConstantInt::get(Ty, *C)); return BinaryOperator::CreateAnd(NewAdd, ConstantInt::get(Ty, *C2)); diff --git a/llvm/test/Transforms/InstCombine/add.ll b/llvm/test/Transforms/InstCombine/add.ll --- a/llvm/test/Transforms/InstCombine/add.ll +++ b/llvm/test/Transforms/InstCombine/add.ll @@ -759,6 +759,19 @@ ret i8 %r } +define i8 @masked_add_multi_use(i8 %x) { +; CHECK-LABEL: @masked_add_multi_use( +; CHECK-NEXT: [[AND:%.*]] = and i8 [[X:%.*]], -16 +; CHECK-NEXT: [[R:%.*]] = add i8 [[AND]], 96 +; CHECK-NEXT: call void @use(i8 [[X]]) +; CHECK-NEXT: ret i8 [[R]] +; + %and = and i8 %x, -16 ; 0xf0 + %r = add i8 %and, 96 ; 0x60 + call void @use(i8 %x) ; extra use + ret i8 %r +} + define i32 @test35(i32 %a) { ; CHECK-LABEL: @test35( ; CHECK-NEXT: ret i32 -1