; NOTE: Assertions have been autogenerated by utils/update_analyze_test_checks.py UTC_ARGS: --version 6 ; RUN: opt < %s -passes='print' -disable-output 2>&1 | FileCheck %s ; for (i = 0; i < btc; i++) ; a[i * (m + 42)] = 0; ; ; We don't know the concret value of `m`, so we cannot deduce no-wrap flags for ; the quotient/remainder divided by `m`. ; define void @divide_by_m0(ptr %a, i64 %m, i64 %btc) { ; CHECK-LABEL: 'divide_by_m0' ; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1 ; CHECK-NEXT: AccessFunction: {0,+,(42 + %m)}<%loop> ; CHECK-NEXT: Base offset: %a ; CHECK-NEXT: ArrayDecl[UnknownSize][%m] with elements of 1 bytes. ; CHECK-NEXT: ArrayRef[{0,+,1}<%loop>][{0,+,42}<%loop>] ; CHECK-NEXT: Delinearization validation: Failed ; entry: %stride = add nsw nuw i64 %m, 42 br label %loop loop: %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] %offset = phi i64 [ 0, %entry ], [ %offset.next, %loop ] %idx = getelementptr inbounds i8, ptr %a, i64 %offset store i8 0, ptr %idx %i.next = add nsw nuw i64 %i, 1 %offset.next = add nsw nuw i64 %offset, %stride %cond = icmp eq i64 %i.next, %btc br i1 %cond, label %exit, label %loop exit: ret void } ; for (int i = 0; i < btc; i++) ; a[i * (2 * m + 42)] = 0; ; ; We don't know the concret value of `m`, so we cannot deduce no-wrap flags for ; the quotient/remainder divided by `m`. ; define void @divide_by_m1(ptr %a, i64 %m, i64 %btc) { ; CHECK-LABEL: 'divide_by_m1' ; CHECK-NEXT: Inst: store i8 0, ptr %idx, align 1 ; CHECK-NEXT: AccessFunction: {0,+,(42 + (2 * %m))}<%loop> ; CHECK-NEXT: Base offset: %a ; CHECK-NEXT: ArrayDecl[UnknownSize][%m] with elements of 1 bytes. ; CHECK-NEXT: ArrayRef[{0,+,2}<%loop>][{0,+,42}<%loop>] ; CHECK-NEXT: Delinearization validation: Failed ; entry: %m2 = add nsw nuw i64 %m, %m %stride = add nsw nuw i64 %m2, 42 br label %loop loop: %i = phi i64 [ 0, %entry ], [ %i.next, %loop ] %offset = phi i64 [ 0, %entry ], [ %offset.next, %loop ] %idx = getelementptr inbounds i8, ptr %a, i64 %offset store i8 0, ptr %idx %i.next = add nsw nuw i64 %i, 1 %offset.next = add nsw nuw i64 %offset, %stride %cond = icmp eq i64 %i.next, %btc br i1 %cond, label %exit, label %loop exit: ret void } ; if (d == 0) ; for (unsigned long long i = 0; i != UINT64_MAX; i++) ; a[i * 2 * d] = 42; ; ; `i * 2 * d` is always zero, so it's nsw and nuw. However, the quotient ; divided by `d` is neither nsw nor nuw. ; define void @divide_by_zero(ptr %a, i64 %d) { ; CHECK-LABEL: 'divide_by_zero' ; CHECK-NEXT: Inst: store i8 42, ptr %idx, align 1 ; CHECK-NEXT: AccessFunction: {0,+,(2 * %d)}<%loop> ; CHECK-NEXT: Base offset: %a ; CHECK-NEXT: ArrayDecl[UnknownSize][%d] with elements of 1 bytes. ; CHECK-NEXT: ArrayRef[{0,+,2}<%loop>][0] ; CHECK-NEXT: Delinearization validation: Failed ; entry: %guard = icmp eq i64 %d, 0 br i1 %guard, label %loop.preheader, label %exit loop.preheader: %stride = mul nsw nuw i64 %d, 2 ; since %d is 0, %stride is also 0 br label %loop loop: %i = phi i64 [ 0, %loop.preheader ], [ %i.next, %loop ] %offset = phi i64 [ 0, %loop.preheader ], [ %offset.next, %loop ] %idx = getelementptr inbounds i8, ptr %a, i64 %offset store i8 42, ptr %idx %i.next = add nuw i64 %i, 1 %offset.next = add nsw nuw i64 %offset, %stride %cond = icmp eq i64 %i.next, -1 br i1 %cond, label %exit, label %loop exit: ret void } ; if (d == UINT64_MAX) ; for (unsigned long long i = 0; i != d; i++) ; a[i * (d + 1)] = 42; ; ; `i * (d + 1)` is always zero, so it's nsw and nuw. However, the ; quotient/remainder divided by `d` is not nsw. ; define void @divide_by_minus_one(ptr %a, i64 %d) { ; CHECK-LABEL: 'divide_by_minus_one' ; CHECK-NEXT: Inst: store i8 42, ptr %idx, align 1 ; CHECK-NEXT: AccessFunction: {0,+,(1 + %d)}<%loop> ; CHECK-NEXT: Base offset: %a ; CHECK-NEXT: ArrayDecl[UnknownSize][%d] with elements of 1 bytes. ; CHECK-NEXT: ArrayRef[{0,+,1}<%loop>][{0,+,1}<%loop>] ; CHECK-NEXT: Delinearization validation: Failed ; entry: %guard = icmp eq i64 %d, -1 br i1 %guard, label %loop.preheader, label %exit loop.preheader: %stride = add nsw i64 %d, 1 ; since %d is -1, %stride is 0 br label %loop loop: %i = phi i64 [ 0, %loop.preheader ], [ %i.next, %loop ] %offset = phi i64 [ 0, %loop.preheader ], [ %offset.next, %loop ] %idx = getelementptr inbounds i8, ptr %a, i64 %offset store i8 42, ptr %idx %i.next = add nuw i64 %i, 1 %offset.next = add nsw nuw i64 %offset, %stride %cond = icmp eq i64 %i.next, %d br i1 %cond, label %exit, label %loop exit: ret void }