Files
clang-p2996/polly/test/Isl/CodeGen/multiple-codegens.ll
Michael Kruse 95ef556bd1 [Polly] Preserve DetectionContext references.
DetectionContext objects are stored as values in a DenseMap. When the
DenseMap reaches its maximum load factor, it is resized and all its
objects moved to a new memory allocation. Unfortunately Scop object have
a reference to its DetectionContext. When the DenseMap resizes, all the
DetectionContexts reference now point to invalid memory, even if caused
by an unrelated DetectionContext.

Even worse, NewPM's ScopPassManager called isMaxRegionInScop with the
Verify=true parameter before each pass. This caused the old
DetectionContext to be removed an a new on created and re-verified.
Of course, the Scop object was already created pointing to the old
DetectionContext. Because the new DetectionContext would
usually be stored at the same position in the DenseMap, the reference
would usually reference the new DetectionContext of the same Region.
Usually.
If not, the old position still points to memory in the DenseMap
allocation (unless also a resizing occurs) such that tools like Valgrind
and AddressSanitizer would not be able to diagnose this.

Instead of storing the DetectionContext inside the DenseMap, use a
std::unique_ptr to a DetectionContext allocation, i.e. it will not move
around anymore. This also allows use to remove the very strange

    DetectionContext(const DetectionContext &&)

copy/move(?) constructor. DetectionContext objects now are neither
copied nor moved.

As a result, every re-verification of a DetectionContext will use a new
allocation. Therefore, once a Scop object has been created using a
DetectionContext, it must not be re-verified (the Scop data structure
requires its underlying Region to not change before code generation
anyway). The NewPM may call isMaxRegionInScop only with
Validate=false parameter.
2021-02-13 03:36:09 -06:00

64 lines
2.0 KiB
LLVM

; RUN: opt %loadPolly -polly-scops -polly-opt-isl -polly-codegen -polly-scops -polly-codegen -S < %s | FileCheck %s
; RUN: opt %loadPolly "-passes=scop(polly-opt-isl,polly-codegen,polly-codegen)" -S < %s | FileCheck %s
; RUN: opt %loadPolly "-passes=scop(polly-opt-isl,polly-codegen),scop(polly-codegen)" -S < %s | FileCheck %s
;
; llvm.org/PR34441
; Properly handle multiple -polly-scops/-polly-codegen in the same
; RegionPassManager. -polly-codegen must not reuse the -polly-ast analysis the
; was created for the first -polly-scops pass.
; The current solution is that only the first -polly-codegen is allowed to
; generate code, the second detects it is re-using an IslAst that belongs to a
; different ScopInfo.
;
; int a, b, c;
;
; int main () {
; while (a++)
; while (b) {
; c = 0;
; break;
; }
; return 0;
; }
;
target datalayout = "e-m:w-i64:64-f80:128-n8:16:32:64-S128"
@a = common global i32 0, align 4
@b = common global i32 0, align 4
@c = common global i32 0, align 4
; Function Attrs: nounwind uwtable
define i32 @main() {
entry:
%retval = alloca i32, align 4
store i32 0, i32* %retval, align 4
%.pre = load i32, i32* @a, align 4
br label %while.cond
while.cond: ; preds = %while.end, %entry
%0 = phi i32 [ %inc, %while.end ], [ %.pre, %entry ]
%inc = add nsw i32 %0, 1
store i32 %inc, i32* @a, align 4
%tobool = icmp ne i32 %0, 0
br i1 %tobool, label %while.body, label %while.end4
while.body: ; preds = %while.cond
%1 = load i32, i32* @b, align 4
%tobool2 = icmp ne i32 %1, 0
br i1 %tobool2, label %while.body3, label %while.end
while.body3: ; preds = %while.body
store i32 0, i32* @c, align 4
br label %while.end
while.end: ; preds = %while.body3, %while.body
br label %while.cond
while.end4: ; preds = %while.cond
ret i32 0
}
; CHECK: polly.start:
; CHECK-NOT: polly.start: