Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -432,8 +432,14 @@ Op0->getOpcode() == Opcode && Op1->getOpcode() == Opcode && match(Op0, m_OneUse(m_BinOp(m_Value(A), m_Constant(C1)))) && match(Op1, m_OneUse(m_BinOp(m_Value(B), m_Constant(C2))))) { - BinaryOperator *NewBO = BinaryOperator::Create(Opcode, A, B); - if (isa(NewBO)) { + bool IsNUW = hasNoUnsignedWrap(I) && + hasNoUnsignedWrap(*Op0) && + hasNoUnsignedWrap(*Op1); + BinaryOperator *NewBO = (IsNUW && Opcode == Instruction::Add) ? + BinaryOperator::CreateNUW(Opcode, A, B) : + BinaryOperator::Create(Opcode, A, B); + + if (isa(NewBO)) { FastMathFlags Flags = I.getFastMathFlags(); Flags &= Op0->getFastMathFlags(); Flags &= Op1->getFastMathFlags(); @@ -446,6 +452,8 @@ // Conservatively clear the optional flags, since they may not be // preserved by the reassociation. ClearSubclassDataAfterReassociation(I); + if (IsNUW) + I.setHasNoUnsignedWrap(true); Changed = true; continue; Index: test/Transforms/InstCombine/reassociate-nuw.ll =================================================================== --- test/Transforms/InstCombine/reassociate-nuw.ll +++ test/Transforms/InstCombine/reassociate-nuw.ll @@ -55,8 +55,8 @@ define i32 @reassoc_x2_add_nuw(i32 %x, i32 %y) { ; CHECK-LABEL: @reassoc_x2_add_nuw( -; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[ADD1]], 12 +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i32 [[X:%.*]], [[Y:%.*]] +; CHECK-NEXT: [[ADD2:%.*]] = add nuw i32 [[ADD1]], 12 ; CHECK-NEXT: ret i32 [[ADD2]] ; %add0 = add nuw i32 %x, 4 @@ -68,7 +68,7 @@ define i32 @reassoc_x2_mul_nuw(i32 %x, i32 %y) { ; CHECK-LABEL: @reassoc_x2_mul_nuw( ; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[X:%.*]], [[Y:%.*]] -; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[MUL1]], 45 +; CHECK-NEXT: [[MUL2:%.*]] = mul nuw i32 [[MUL1]], 45 ; CHECK-NEXT: ret i32 [[MUL2]] ; %mul0 = mul nuw i32 %x, 5