[CodeGen] Detect impossible partial write conditions more reliably.

Whether a partial write is tautological/unsatisfiable not only
depends on the access domain, but also on the domain covered
by its node in the AST.

In the example below, there are two instances of Stmt_cond_false. It may have a partial write access that is not executed in instance Stmt_cond_false(0).

      for (int c0 = 0; c0 < tmp5; c0 += 1) {
        Stmt_for_body344(c0);
        if (tmp5 >= c0 + 2)
          Stmt_cond_false(c0);
        Stmt_cond_end(c0);
      }
      if (tmp5 <= 0) {
        Stmt_for_body344(0);
        Stmt_cond_false(0);
        Stmt_cond_end(0);
      }

Isl cannot derive a subscript for an array element that is never accessed.
This caused an error in that no subscript expression has been generated
in IslNodeBuilder::createNewAccesses, but BlockGenerator expected one
to exist because there is an execution of that write, just not in that
ast node.

Fixed by instead of determining whether the access domain is empty,
inspect whether isl generated a constant "false" ast expression in
the current ast node.

This should fix a compiler crash of the aosp buildbot.

llvm-svn: 311663
This commit is contained in:
Michael Kruse 2017-08-24 14:51:35 +00:00
parent b0eb5fb317
commit b795bfc0d4
4 changed files with 184 additions and 5 deletions

View File

@ -601,11 +601,6 @@ void BlockGenerator::generateConditionalExecution(
const std::function<void()> &GenThenFunc) {
isl::set StmtDom = Stmt.getDomain();
// Don't call GenThenFunc if it is never executed. An ast index expression
// might not be defined in this case.
if (Subdomain.is_empty())
return;
// If the condition is a tautology, don't generate a condition around the
// code.
bool IsPartialWrite =
@ -618,6 +613,13 @@ void BlockGenerator::generateConditionalExecution(
// Generate the condition.
Value *Cond = buildContainsCondition(Stmt, Subdomain);
// Don't call GenThenFunc if it is never executed. An ast index expression
// might not be defined in this case.
if (auto *Const = dyn_cast<ConstantInt>(Cond))
if (Const->isZero())
return;
BasicBlock *HeadBlock = Builder.GetInsertBlock();
StringRef BlockName = HeadBlock->getName();

View File

@ -0,0 +1,59 @@
; RUN: opt %loadPolly -polly-import-jscop -polly-import-jscop-postfix=transformed -polly-codegen -S < %s | FileCheck %s
;
; The isl scheduler isolates %cond.false into two instances.
; A partial write access in one of the instances was never executed,
; which caused problems when querying for its index expression, which
; is not available in that case.
;
target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
define void @partial_write_impossible_restriction() {
entry:
br i1 undef, label %invoke.cont258, label %cond.true.i.i.i.i1007
cond.true.i.i.i.i1007:
br label %invoke.cont258
invoke.cont258:
%.pn = phi i32* [ null, %cond.true.i.i.i.i1007 ], [ null, %entry ]
br label %invoke.cont274
invoke.cont274: ; preds = %invoke.cont258
%tmp4 = load i32*, i32** undef
%tmp5 = load i32, i32* undef
%tmp6 = zext i32 %tmp5 to i64
%tmp7 = sext i32 %tmp5 to i64
br label %for.body344
for.body344: ; preds = %cond.end, %invoke.cont274
%indvars.iv1602 = phi i64 [ 0, %invoke.cont274 ], [ %indvars.iv.next1603, %cond.end ]
%indvars.iv.next1603 = add nuw nsw i64 %indvars.iv1602, 1
%cmp347 = icmp eq i64 %indvars.iv.next1603, %tmp6
br i1 %cmp347, label %cond.end, label %cond.false
cond.false: ; preds = %for.body344
%add.ptr.i1128 = getelementptr inbounds i32, i32* %tmp4, i64 %indvars.iv.next1603
%cond.in.sroa.speculate.load.cond.false = load i32, i32* %add.ptr.i1128
br label %cond.end
cond.end: ; preds = %cond.false, %for.body344
%cond.in.sroa.speculated = phi i32 [ %cond.in.sroa.speculate.load.cond.false, %cond.false ], [ undef, %for.body344 ]
%add.ptr.i1132 = getelementptr inbounds i32, i32* %.pn, i64 %indvars.iv1602
store i32 undef, i32* %add.ptr.i1132
%cmp342 = icmp slt i64 %indvars.iv.next1603, %tmp7
br i1 %cmp342, label %for.body344, label %if.then.i.i1141.loopexit
if.then.i.i1141.loopexit: ; preds = %cond.end
ret void
}
; CHECK-LABEL: polly.stmt.cond.false:
; CHECK: %polly.access..pn2 = getelementptr i32, i32* %.pn, i64 %polly.indvar
; CHECK: store i32 %cond.in.sroa.speculate.load.cond.false_p_scalar_, i32* %polly.access..pn2, !alias.scope !0, !noalias !2
; CHECK: br label %polly.merge
; CHECK-LABEL: polly.stmt.cond.false11:
; CHECK: %polly.access..pn14 = getelementptr i32, i32* %.pn, i64 0
; CHECK: store i32 %cond.in.sroa.speculate.load.cond.false_p_scalar_13, i32* %polly.access..pn14, !alias.scope !0, !noalias !2
; CHECK: br label %polly.stmt.cond.end15

View File

@ -0,0 +1,59 @@
{
"arrays" : [
{
"name" : "MemRef_tmp4",
"sizes" : [ "*" ],
"type" : "i32"
},
{
"name" : "MemRef__pn",
"sizes" : [ "*" ],
"type" : "i32"
}
],
"context" : "[tmp5] -> { : -2147483648 <= tmp5 <= 2147483647 }",
"name" : "%for.body344---%if.then.i.i1141.loopexit",
"statements" : [
{
"accesses" : [
{
"kind" : "write",
"relation" : "[tmp5] -> { Stmt_for_body344[i0] -> MemRef_cond_in_sroa_speculated__phi[] }"
}
],
"domain" : "[tmp5] -> { Stmt_for_body344[i0] : 0 <= i0 < tmp5; Stmt_for_body344[0] : tmp5 <= 0 }",
"name" : "Stmt_for_body344",
"schedule" : "[tmp5] -> { Stmt_for_body344[i0] -> [i0, 0] : i0 < tmp5; Stmt_for_body344[0] -> [0, 0] : tmp5 <= 0 }"
},
{
"accesses" : [
{
"kind" : "read",
"relation" : "[tmp5] -> { Stmt_cond_false[i0] -> MemRef_tmp4[1 + i0] }"
},
{
"kind" : "write",
"relation" : "[tmp5] -> { Stmt_cond_false[i0] -> MemRef_cond_in_sroa_speculated__phi[] }"
}
],
"domain" : "[tmp5] -> { Stmt_cond_false[i0] : 0 <= i0 <= -2 + tmp5; Stmt_cond_false[0] : tmp5 <= 0 }",
"name" : "Stmt_cond_false",
"schedule" : "[tmp5] -> { Stmt_cond_false[i0] -> [i0, 1] : i0 <= -2 + tmp5; Stmt_cond_false[0] -> [0, 1] : tmp5 <= 0 }"
},
{
"accesses" : [
{
"kind" : "read",
"relation" : "[tmp5] -> { Stmt_cond_end[i0] -> MemRef_cond_in_sroa_speculated__phi[] }"
},
{
"kind" : "write",
"relation" : "[tmp5] -> { Stmt_cond_end[i0] -> MemRef__pn[i0] }"
}
],
"domain" : "[tmp5] -> { Stmt_cond_end[i0] : 0 <= i0 < tmp5; Stmt_cond_end[0] : tmp5 <= 0 }",
"name" : "Stmt_cond_end",
"schedule" : "[tmp5] -> { Stmt_cond_end[i0] -> [i0, 2] : i0 < tmp5; Stmt_cond_end[0] -> [0, 2] : tmp5 <= 0 }"
}
]
}

View File

@ -0,0 +1,59 @@
{
"arrays" : [
{
"name" : "MemRef_tmp4",
"sizes" : [ "*" ],
"type" : "i32"
},
{
"name" : "MemRef__pn",
"sizes" : [ "*" ],
"type" : "i32"
}
],
"context" : "[tmp5] -> { : -2147483648 <= tmp5 <= 2147483647 }",
"name" : "%for.body344---%if.then.i.i1141.loopexit",
"statements" : [
{
"accesses" : [
{
"kind" : "write",
"relation" : "[tmp5] -> { Stmt_for_body344[-1 + tmp5] -> MemRef__pn[-1 + tmp5] }"
}
],
"domain" : "[tmp5] -> { Stmt_for_body344[i0] : 0 <= i0 < tmp5; Stmt_for_body344[0] : tmp5 <= 0 }",
"name" : "Stmt_for_body344",
"schedule" : "[tmp5] -> { Stmt_for_body344[i0] -> [i0, 0] : i0 < tmp5; Stmt_for_body344[0] -> [0, 0] : tmp5 <= 0 }"
},
{
"accesses" : [
{
"kind" : "read",
"relation" : "[tmp5] -> { Stmt_cond_false[i0] -> MemRef_tmp4[1 + i0] }"
},
{
"kind" : "write",
"relation" : "[tmp5] -> { Stmt_cond_false[i0] -> MemRef__pn[i0] : i0 <= -2 + tmp5; Stmt_cond_false[0] -> MemRef__pn[0] : tmp5 <= 0 }"
}
],
"domain" : "[tmp5] -> { Stmt_cond_false[i0] : 0 <= i0 <= -2 + tmp5; Stmt_cond_false[0] : tmp5 <= 0 }",
"name" : "Stmt_cond_false",
"schedule" : "[tmp5] -> { Stmt_cond_false[i0] -> [i0, 1] : i0 <= -2 + tmp5; Stmt_cond_false[0] -> [0, 1] : tmp5 <= 0 }"
},
{
"accesses" : [
{
"kind" : "read",
"relation" : "[tmp5] -> { Stmt_cond_end[i0] -> MemRef__pn[i0] }"
},
{
"kind" : "write",
"relation" : "[tmp5] -> { Stmt_cond_end[i0] -> MemRef__pn[i0] }"
}
],
"domain" : "[tmp5] -> { Stmt_cond_end[i0] : 0 <= i0 < tmp5; Stmt_cond_end[0] : tmp5 <= 0 }",
"name" : "Stmt_cond_end",
"schedule" : "[tmp5] -> { Stmt_cond_end[i0] -> [i0, 2] : i0 < tmp5; Stmt_cond_end[0] -> [0, 2] : tmp5 <= 0 }"
}
]
}