blob: 96df5a93f47b2a9bed2f21c878d60f01be4504dd [file] [edit]
; RUN: opt %loadNPMPolly '-passes=polly-custom<scops>' -plugin-arg=Polly,-polly-print-scops -disable-output < %s 2>&1 | FileCheck %s
; RUN: opt %loadNPMPolly '-passes=polly-custom<ast>' -plugin-arg=Polly,-polly-print-ast -disable-output < %s 2>&1 | FileCheck %s --check-prefix=AST
;
; https://github.com/llvm/llvm-project/issues/192616
; https://github.com/llvm/llvm-project/issues/192618
;
; The loop bound (zext i16 %n to i64) is modeled as 'n' under the assumption
; that n is non-negative. For n < 0, the model's exit condition is never
; satisfied and the loop appears to be unbounded. Since the induction variable
; is <nsw>, an unbounded loop would be undefined behavior, which removes
; n < 0 from the loop's domain without a runtime check. In reality, the loop
; executes 65536 + n iterations, i.e. the non-negativity assumption must be
; checked at runtime.
;
; void f(char *A, unsigned short *N) {
; unsigned short n = *N;
; if (n == 0)
; return;
; long i = 0;
; do
; A[i] = 1;
; while (++i != n);
; }
; CHECK: Invalid Context:
; CHECK-NEXT: [n] -> { : n < 0 }
; CHECK: Domain :=
; CHECK-NEXT: [n] -> { Stmt_for[i0] : 0 <= i0 < n };
; AST: if (1 && 0 == n <= -1)
; AST-EMPTY:
; AST-NEXT: for (int c0 = 0; c0 < n; c0 += 1)
; AST-NEXT: Stmt_for(c0);
define void @f(ptr %A, ptr %N) {
entry:
%n = load i16, ptr %N
%nz = zext i16 %n to i64
%nonzero = icmp ne i16 %n, 0
br i1 %nonzero, label %for, label %exit
for:
%i = phi i64 [ 0, %entry ], [ %i.next, %for ]
%gep = getelementptr inbounds i8, ptr %A, i64 %i
store i8 1, ptr %gep
%i.next = add nuw nsw i64 %i, 1
%done = icmp eq i64 %i.next, %nz
br i1 %done, label %exit, label %for
exit:
ret void
}