Index: lib/Transforms/InstCombine/InstructionCombining.cpp =================================================================== --- lib/Transforms/InstCombine/InstructionCombining.cpp +++ lib/Transforms/InstCombine/InstructionCombining.cpp @@ -223,6 +223,11 @@ return !Overflow; } +static bool hasNoUnsignedWrap(BinaryOperator &I) { + OverflowingBinaryOperator *OBO = dyn_cast(&I); + return OBO && OBO->hasNoUnsignedWrap(); +} + /// Conservatively clears subclassOptionalData after a reassociation or /// commutation. We preserve fast-math flags when applicable as they can be /// preserved. @@ -329,14 +334,20 @@ I.setOperand(1, V); // Conservatively clear the optional flags, since they may not be // preserved by the reassociation. - if (MaintainNoSignedWrap(I, B, C) && + + bool IsNUW = hasNoUnsignedWrap(I); + bool IsNSW = MaintainNoSignedWrap(I, B, C); + + ClearSubclassDataAfterReassociation(I); + + if (IsNUW && hasNoUnsignedWrap(*Op0)) + I.setHasNoUnsignedWrap(true); + + if (IsNSW && (!Op0 || (isa(Op0) && Op0->hasNoSignedWrap()))) { // Note: this is only valid because SimplifyBinOp doesn't look at // the operands to Op0. - I.clearSubclassOptionalData(); I.setHasNoSignedWrap(true); - } else { - ClearSubclassDataAfterReassociation(I); } Changed = true; Index: test/Transforms/InstCombine/reassociate-nuw.ll =================================================================== --- test/Transforms/InstCombine/reassociate-nuw.ll +++ test/Transforms/InstCombine/reassociate-nuw.ll @@ -3,7 +3,7 @@ define i32 @reassoc_add_nuw(i32 %x) { ; CHECK-LABEL: @reassoc_add_nuw( -; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X:%.*]], 68 +; CHECK-NEXT: [[ADD1:%.*]] = add nuw i32 [[X:%.*]], 68 ; CHECK-NEXT: ret i32 [[ADD1]] ; %add0 = add nuw i32 %x, 4 Index: test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll =================================================================== --- test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll +++ test/Transforms/LoopUnroll/runtime-loop-multiple-exits.ll @@ -172,7 +172,7 @@ ; PROLOG: loop_exiting_bb1.7: ; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7 ; PROLOG: loop_latch.7: -; PROLOG-NEXT: %iv_next.7 = add nsw i64 %iv, 8 +; PROLOG-NEXT: %iv_next.7 = add nuw nsw i64 %iv, 8 ; PROLOG-NEXT: %sum.next.7 = add i64 %sum.next.6, %add ; PROLOG-NEXT: %cmp.7 = icmp eq i64 %iv_next.7, %trip ; PROLOG-NEXT: br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header @@ -426,7 +426,7 @@ ; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ] ; PROLOG-NEXT: ret i64 %result ; PROLOG: loop_latch.7: -; PROLOG: %iv_next.7 = add nsw i64 %iv, 8 +; PROLOG: %iv_next.7 = add nuw nsw i64 %iv, 8 entry: br label %loop_header @@ -560,7 +560,7 @@ } ; Nested loop and inner loop is unrolled -; FIXME: we cannot unroll with epilog remainder currently, because +; FIXME: we cannot unroll with epilog remainder currently, because ; the outer loop does not contain the epilog preheader and epilog exit (while ; infact it should). This causes us to choke up on LCSSA form being incorrect in ; outer loop. However, the exit block where LCSSA fails, is infact still within @@ -578,7 +578,7 @@ ; PROLOG: %lcmp.mod = icmp eq i64 ; PROLOG-NEXT: br i1 %lcmp.mod, label %innerH.prol.loopexit, label %innerH.prol.preheader ; PROLOG: latch.6: -; PROLOG-NEXT: %tmp4.7 = add nsw i64 %tmp3, 8 +; PROLOG-NEXT: %tmp4.7 = add nuw nsw i64 %tmp3, 8 ; PROLOG-NEXT: br i1 false, label %outerloop.loopexit.loopexit, label %latch.7 ; PROLOG: latch.7 ; PROLOG-NEXT: %tmp6.7 = icmp ult i64 %tmp4.7, 100