Skip to content

Commit a01710e

Browse files
Serguei Katkovmemfrob
authored andcommitted
[GuardWidening] Remove nuw/nsw flags for hoisted instructions
When we hoist instructions over guard we must clear flags due to these flags might be implied using this guard, so they make sense only after the guard. As an example of the bug due to current behavior. L is known to be in range say [0, 100) c1 = x u< L guard (c1) x1 = add x, 1 c2 = x1 u< L guard(c2) basing on guard(c1) we can say that x1 = add nuw nsw x, 1 after guard widening we get c1 = x u< L x1 = add nuw nsw x, 1 c2 = x1 u< L c = and c1, c2 guard(c) now, basing on fact that x + 1 < L and x >= 0 due to x + 1 is nuw we can prove that x + 1 u< L implies that x u< L, so we can just remove c1 x1 = add nuw nsw x, 1 c2 = x1 u< L guard(c2) But that is not correct due to we will pass x == -1 value. Reviewed By: mkazantsev Subscribers: llvm-commits, nikic Differential Revision: https://reviews.llvm.org/D126354
1 parent 2e4ec0d commit a01710e

File tree

2 files changed

+4
-1
lines changed

2 files changed

+4
-1
lines changed

llvm/lib/Transforms/Scalar/GuardWidening.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,9 @@ void GuardWideningImpl::makeAvailableAt(Value *V, Instruction *Loc) const {
495495
makeAvailableAt(Op, Loc);
496496

497497
Inst->moveBefore(Loc);
498+
// If we moved instruction before guard we must clean nuw, nsw flags.
499+
Inst->setHasNoUnsignedWrap(false);
500+
Inst->setHasNoSignedWrap(false);
498501
}
499502

500503
bool GuardWideningImpl::widenCondCommon(Value *Cond0, Value *Cond1,

llvm/test/Transforms/GuardWidening/range-check-merging.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ define void @f_8(i32 %x, i32* %length_buf) {
340340
; CHECK-NEXT: entry:
341341
; CHECK-NEXT: [[LENGTH:%.*]] = load i32, i32* [[LENGTH_BUF:%.*]], align 4, !range [[RNG0]]
342342
; CHECK-NEXT: [[CHK0:%.*]] = icmp ult i32 [[X:%.*]], [[LENGTH]]
343-
; CHECK-NEXT: [[X_INC1:%.*]] = add nuw nsw i32 [[X]], 1
343+
; CHECK-NEXT: [[X_INC1:%.*]] = add i32 [[X]], 1
344344
; CHECK-NEXT: [[CHK1:%.*]] = icmp ult i32 [[X_INC1]], [[LENGTH]]
345345
; CHECK-NEXT: [[WIDE_CHK:%.*]] = and i1 [[CHK0]], [[CHK1]]
346346
; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[WIDE_CHK]]) [ "deopt"() ]

0 commit comments

Comments
 (0)