2022-03-14 21:39:25 +08:00
; RUN: opt %loadPolly -polly-print-scops -polly-print-delicm -disable-output < %s | FileCheck %s
[Polly] Track defined behavior for PHI predecessor computation.
ZoneAlgorithms's computePHI relies on being provided with consistent a
schedule to compute the statement prodecessors of a statement containing
PHINodes. Otherwise unexpected results such as PHI nodes with multiple
predecessors can occur which would result in problems in the
algorithms expecting consistent data.
In the added test case, statement instances are scrubbed from the
SCoP their execution would result in undefined behavior (Due to a nsw
overflow). As already being undefined behavior in LLVM-IR, neither
AssumedContext nor InvalidContext are updated, giving computePHI no
means to avoid these cases.
Intoduce a new SCoP property, the DefinedBehaviorContext, that among
the runtime-checked conditions, also tracks the assumptions not needing
a runtime check, in particular those affecting the assumed control flow.
This replaces the manual combination of the 3 other contexts that was
already done in computePHI and setNewAccessRelation. Currently, the only
additional assumption is that loop induction variables will nsw flag for
not wrap, but potentially more can be added. Use in
hasFeasibleRuntimeContext, isl::ast_build and gisting are other
potential uses.
To limit computational complexity, the DefinedBehaviorContext is not
availabe if it grows too large (atm hardcoded to 8 disjuncts).
Possible other fixes include bailing out in computePHI when
inconsistencies are detected, choose an arbitrary value for inconsistent
cases (since it is undefined behavior anyways), or make the code
receiving the result from ComputePHI handle inconsistent data. All of
them reduce the quality of implementation having to bail out more often
and disabling the ability to assert on actually wrong results.
This fixes llvm.org/PR48783.
2021-01-22 11:20:53 +08:00
;
; llvm.org/PR48783
;
; PHI predecessors of statement instances can only be reliably derived in defined behaviour situations. In this case, the inner loop's counter would overflow when its upper bound (%call24) is lower than its lower bound (2). However, due to the nsw flag, this would be undefined behavior and therefore not added to any runtime-check context, but to the defined-behaviour context.
;
; Dereived from test case pr41656.ll
;
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
define d s o _ l o c a l void @main ( ) local_unnamed_addr #0 {
entry:
%call24 = tail call i32 @av_get_channel_layout_nb_channels ( ) #2
br label %if.end30
if.end30: ; preds = %entry
br i1 undef , label %if.then40 , label %do.body.preheader
do.body.preheader: ; preds = %if.end30
%idx.ext.i = sext i32 %call24 to i64
%wide.trip.count.i = zext i32 %call24 to i64
%0 = load double * , double * * undef , align 8 , !tbaa !1
br label %for.body.us.preheader.i
if.then40: ; preds = %if.end30
unreachable
for.body.us.preheader.i: ; preds = %do.body.preheader
br i1 false , label %for.body.us.i.us , label %for.body.us.i
for.body.us.i.us: ; preds = %for.body.us.preheader.i
br label %fill_samples.exit
for.body.us.i: ; preds = %for.cond2.for.end_crit_edge.us.i, %for.body.us.preheader.i
%t.1 = phi double [ undef , %for.cond2.for.end_crit_edge.us.i ] , [ 0.000000e+00 , %for.body.us.preheader.i ]
%i.05.us.i = phi i32 [ %inc8.us.i , %for.cond2.for.end_crit_edge.us.i ] , [ 0 , %for.body.us.preheader.i ]
%dstp.03.us.i = phi double * [ %add.ptr.us.i , %for.cond2.for.end_crit_edge.us.i ] , [ %0 , %for.body.us.preheader.i ]
%mul.us.i = fmul nsz double %t.1 , 0x40A59933FC6A96C1
%1 = call nsz double @llvm.sin.f64 ( double %mul.us.i ) #2
store double %1 , double * %dstp.03.us.i , align 8 , !tbaa !5
%2 = bitcast double * %dstp.03.us.i to i64 *
br label %for.body5.us.for.body5.us_crit_edge.i
for.body5.us.for.body5.us_crit_edge.i: ; preds = %for.body5.us.for.body5.us_crit_edge.i.for.body5.us.for.body5.us_crit_edge.i_crit_edge, %for.body.us.i
%indvars.iv.next.i66 = phi i64 [ 2 , %for.body.us.i ] , [ %indvars.iv.next.i , %for.body5.us.for.body5.us_crit_edge.i.for.body5.us.for.body5.us_crit_edge.i_crit_edge ]
%indvars.iv.next.i = add nuw nsw i64 %indvars.iv.next.i66 , 1
udiv i64 1 , %indvars.iv.next.i
%exitcond.i = icmp eq i64 %indvars.iv.next.i , %wide.trip.count.i
br i1 %exitcond.i , label %for.cond2.for.end_crit_edge.us.i , label %for.body5.us.for.body5.us_crit_edge.i.for.body5.us.for.body5.us_crit_edge.i_crit_edge
for.body5.us.for.body5.us_crit_edge.i.for.body5.us.for.body5.us_crit_edge.i_crit_edge: ; preds = %for.body5.us.for.body5.us_crit_edge.i
%.pre10.i.pre = load i64 , i64 * %2 , align 8 , !tbaa !5
br label %for.body5.us.for.body5.us_crit_edge.i
for.cond2.for.end_crit_edge.us.i: ; preds = %for.body5.us.for.body5.us_crit_edge.i
%add.ptr.us.i = getelementptr inbounds double , double * %dstp.03.us.i , i64 %idx.ext.i
%inc8.us.i = add nuw nsw i32 %i.05.us.i , 1
%exitcond7.i = icmp eq i32 %inc8.us.i , 1024
br i1 %exitcond7.i , label %fill_samples.exit , label %for.body.us.i
fill_samples.exit: ; preds = %for.cond2.for.end_crit_edge.us.i, %for.body.us.i.us
ret void
}
2022-02-23 05:37:50 +08:00
[Polly] Track defined behavior for PHI predecessor computation.
ZoneAlgorithms's computePHI relies on being provided with consistent a
schedule to compute the statement prodecessors of a statement containing
PHINodes. Otherwise unexpected results such as PHI nodes with multiple
predecessors can occur which would result in problems in the
algorithms expecting consistent data.
In the added test case, statement instances are scrubbed from the
SCoP their execution would result in undefined behavior (Due to a nsw
overflow). As already being undefined behavior in LLVM-IR, neither
AssumedContext nor InvalidContext are updated, giving computePHI no
means to avoid these cases.
Intoduce a new SCoP property, the DefinedBehaviorContext, that among
the runtime-checked conditions, also tracks the assumptions not needing
a runtime check, in particular those affecting the assumed control flow.
This replaces the manual combination of the 3 other contexts that was
already done in computePHI and setNewAccessRelation. Currently, the only
additional assumption is that loop induction variables will nsw flag for
not wrap, but potentially more can be added. Use in
hasFeasibleRuntimeContext, isl::ast_build and gisting are other
potential uses.
To limit computational complexity, the DefinedBehaviorContext is not
availabe if it grows too large (atm hardcoded to 8 disjuncts).
Possible other fixes include bailing out in computePHI when
inconsistencies are detected, choose an arbitrary value for inconsistent
cases (since it is undefined behavior anyways), or make the code
receiving the result from ComputePHI handle inconsistent data. All of
them reduce the quality of implementation having to bail out more often
and disabling the ability to assert on actually wrong results.
This fixes llvm.org/PR48783.
2021-01-22 11:20:53 +08:00
declare d s o _ l o c a l i32 @av_get_channel_layout_nb_channels ( ) local_unnamed_addr #0
; Function Attrs: nounwind readnone speculatable
declare double @llvm.sin.f64 ( double ) #1
attributes #0 = { "use-soft-float" = "false" }
attributes #1 = { nounwind readnone s p e c u l a t a b l e }
attributes #2 = { nounwind }
!llvm.ident = ! { !0 }
!0 = ! { !"clang version 9.0.0 (https://github.com/llvm/llvm-project.git 2436237895b70ed44cf256f67eb2f74e147eb559)" }
!1 = ! { !2 , !2 , i64 0 }
!2 = ! { !"any pointer" , !3 , i64 0 }
!3 = ! { !"omnipotent char" , !4 , i64 0 }
!4 = ! { !"Simple C/C++ TBAA" }
!5 = ! { !6 , !6 , i64 0 }
!6 = ! { !"double" , !3 , i64 0 }
; CHECK: Invalid Context:
; CHECK-NEXT: [call24] -> { : false }
; CHECK: Defined Behavior Context:
; CHECK-NEXT: [call24] -> { : 3 <= call24 <= 2147483647 }
; Only write to scalar if call24 >= 3 (i.e. has defined behavior)
; Since it should be never executed otherwise, the condition is not strictly necessary.
; CHECK-LABEL: DeLICM result:
; CHECK: Stmt_for_body_us_preheader_i
; CHECK-NEXT: MustWriteAccess := [Reduction Type: NONE] [Scalar: 1]
; CHECK-NEXT: [call24] -> { Stmt_for_body_us_preheader_i[] -> MemRef_t_1__phi[] };
; CHECK-NEXT: new: [call24] -> { Stmt_for_body_us_preheader_i[] -> MemRef1[0, 0] : call24 >= 3 };