forked from OSchip/llvm-project
InstCombine: Preserve nuw when reassociating nuw ops [1/3]
Alive says this is OK. llvm-svn: 364233
This commit is contained in:
parent
1e5116cbb3
commit
5a89ba7343
|
@ -223,6 +223,11 @@ static bool MaintainNoSignedWrap(BinaryOperator &I, Value *B, Value *C) {
|
||||||
return !Overflow;
|
return !Overflow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool hasNoUnsignedWrap(BinaryOperator &I) {
|
||||||
|
OverflowingBinaryOperator *OBO = dyn_cast<OverflowingBinaryOperator>(&I);
|
||||||
|
return OBO && OBO->hasNoUnsignedWrap();
|
||||||
|
}
|
||||||
|
|
||||||
/// Conservatively clears subclassOptionalData after a reassociation or
|
/// Conservatively clears subclassOptionalData after a reassociation or
|
||||||
/// commutation. We preserve fast-math flags when applicable as they can be
|
/// commutation. We preserve fast-math flags when applicable as they can be
|
||||||
/// preserved.
|
/// preserved.
|
||||||
|
@ -329,14 +334,19 @@ bool InstCombiner::SimplifyAssociativeOrCommutative(BinaryOperator &I) {
|
||||||
I.setOperand(1, V);
|
I.setOperand(1, V);
|
||||||
// Conservatively clear the optional flags, since they may not be
|
// Conservatively clear the optional flags, since they may not be
|
||||||
// preserved by the reassociation.
|
// preserved by the reassociation.
|
||||||
if (MaintainNoSignedWrap(I, B, C) &&
|
bool IsNUW = hasNoUnsignedWrap(I) && hasNoUnsignedWrap(*Op0);
|
||||||
|
bool IsNSW = MaintainNoSignedWrap(I, B, C);
|
||||||
|
|
||||||
|
ClearSubclassDataAfterReassociation(I);
|
||||||
|
|
||||||
|
if (IsNUW)
|
||||||
|
I.setHasNoUnsignedWrap(true);
|
||||||
|
|
||||||
|
if (IsNSW &&
|
||||||
(!Op0 || (isa<BinaryOperator>(Op0) && Op0->hasNoSignedWrap()))) {
|
(!Op0 || (isa<BinaryOperator>(Op0) && Op0->hasNoSignedWrap()))) {
|
||||||
// Note: this is only valid because SimplifyBinOp doesn't look at
|
// Note: this is only valid because SimplifyBinOp doesn't look at
|
||||||
// the operands to Op0.
|
// the operands to Op0.
|
||||||
I.clearSubclassOptionalData();
|
|
||||||
I.setHasNoSignedWrap(true);
|
I.setHasNoSignedWrap(true);
|
||||||
} else {
|
|
||||||
ClearSubclassDataAfterReassociation(I);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Changed = true;
|
Changed = true;
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
|
|
||||||
define i32 @reassoc_add_nuw(i32 %x) {
|
define i32 @reassoc_add_nuw(i32 %x) {
|
||||||
; CHECK-LABEL: @reassoc_add_nuw(
|
; 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]]
|
; CHECK-NEXT: ret i32 [[ADD1]]
|
||||||
;
|
;
|
||||||
%add0 = add nuw i32 %x, 4
|
%add0 = add nuw i32 %x, 4
|
||||||
|
|
|
@ -172,7 +172,7 @@ define void @test3(i64 %trip, i64 %add) {
|
||||||
; PROLOG: loop_exiting_bb1.7:
|
; PROLOG: loop_exiting_bb1.7:
|
||||||
; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7
|
; PROLOG-NEXT: switch i64 %sum.next.6, label %loop_latch.7
|
||||||
; PROLOG: 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: %sum.next.7 = add i64 %sum.next.6, %add
|
||||||
; PROLOG-NEXT: %cmp.7 = icmp eq i64 %iv_next.7, %trip
|
; 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
|
; PROLOG-NEXT: br i1 %cmp.7, label %exit2.loopexit.unr-lcssa, label %loop_header
|
||||||
|
@ -426,7 +426,7 @@ define i64 @test5(i64 %trip, i64 %add, i1 %cond) {
|
||||||
; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ]
|
; PROLOG-NEXT: %result = phi i64 [ %result.ph, %exit1.loopexit ], [ %ivy.prol, %exit1.loopexit1 ]
|
||||||
; PROLOG-NEXT: ret i64 %result
|
; PROLOG-NEXT: ret i64 %result
|
||||||
; PROLOG: loop_latch.7:
|
; PROLOG: loop_latch.7:
|
||||||
; PROLOG: %iv_next.7 = add nsw i64 %iv, 8
|
; PROLOG: %iv_next.7 = add nuw nsw i64 %iv, 8
|
||||||
entry:
|
entry:
|
||||||
br label %loop_header
|
br label %loop_header
|
||||||
|
|
||||||
|
@ -560,7 +560,7 @@ loopexit1: ; preds = %header
|
||||||
}
|
}
|
||||||
|
|
||||||
; Nested loop and inner loop is unrolled
|
; 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
|
; 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
|
; 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
|
; outer loop. However, the exit block where LCSSA fails, is infact still within
|
||||||
|
@ -578,7 +578,7 @@ define void @test8() {
|
||||||
; PROLOG: %lcmp.mod = icmp eq i64
|
; PROLOG: %lcmp.mod = icmp eq i64
|
||||||
; PROLOG-NEXT: br i1 %lcmp.mod, label %innerH.prol.loopexit, label %innerH.prol.preheader
|
; PROLOG-NEXT: br i1 %lcmp.mod, label %innerH.prol.loopexit, label %innerH.prol.preheader
|
||||||
; PROLOG: latch.6:
|
; 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-NEXT: br i1 false, label %outerloop.loopexit.loopexit, label %latch.7
|
||||||
; PROLOG: latch.7
|
; PROLOG: latch.7
|
||||||
; PROLOG-NEXT: %tmp6.7 = icmp ult i64 %tmp4.7, 100
|
; PROLOG-NEXT: %tmp6.7 = icmp ult i64 %tmp4.7, 100
|
||||||
|
|
Loading…
Reference in New Issue