[polly] ScalarEvolution not supporting SDiv, SRem [was: r244903 - Add test case for SCEV synthesizing]

Michael Kruse via llvm-commits llvm-commits at lists.llvm.org
Fri Aug 14 12:16:19 PDT 2015


There is a larger issue behind this test case that cannot be fixed easily.

This particular test case is somewhat dump because %div44 = sdiv i64
0, 2 is constant. It could be optimized away using InstCombine. Before
bugpoint it was not constant. About 6 programs from the test-suite
(did not look into all of them, assuming because the same assert
triggers) failed because of this when allowing PHI nodes in exit
blocks.

The cause is the following:

As an exception, polly::SCEVValidator accepts SDiv and SRem
instructions, for which no SCEV representation exists. They appear as
SCEVUnknown. polly::SCEVAffinator has been taught how to generate an
isl_pw_aff for them. When used as a scop parameter, llvm::SCEVExpander
is used to generate IR code. It doesn't know about the SDiv/SRem
extension and is happy to generate code referencing the SDiv/SRem that
might be defined only later within the scop.

AFAIK such uses of SCEVExpander can only occur for scop parameters,
but nothing within the scop. Everything from within the scop is
generated from the isl_ast/isl_pw_aff.


Possible solutions:

1.) Remove the extension for SDiv/SRem

2.) Teach ScalarEvolution handle SDiv and SRem, including the
introduction of SCEVSDivExpr and SCEVSRemExpr. This requires changing
LLVM itself.

3.) Copy&Paste LLVM's llvm::SCEVExpander and modify it such that it
generates code for the SDiv and SRem instructions as well.

4.) Fix it up after SCEVExpander: Copy instructions/expression trees
that are referenced in the generated code,(but defined later) to
before the generated code. This possible because SCEVValidator checks
that the operands (and their operands, recursively) are
scop-invariant.

5.) Demote SCEV's with SRem/SDiv instruction to at most IV, so they
cannot appear in SCEVs outside of the loop. (Makes 4 test cases fail).

6.) Move scop-invariant SRem/SDivs to polly.split_new_and old before
CodeGeneration.


Opinions? IMHO 2.) is the cleanest. 4.) and 6.) would be a quick fixups.

Michael



2015-08-13 17:53 GMT+02:00 Michael Kruse via llvm-commits
<llvm-commits at lists.llvm.org>:
> Author: meinersbur
> Date: Thu Aug 13 10:53:53 2015
> New Revision: 244903
>
> URL: http://llvm.org/viewvc/llvm-project?rev=244903&view=rev
> Log:
> Add test case for SCEV synthesizing
>
> CodeGenerator currently tries to generate code for a parameter using
> values values that are computed later.
>
>
> Added:
>     polly/trunk/test/Isl/CodeGen/inner_scev.ll
>
> Added: polly/trunk/test/Isl/CodeGen/inner_scev.ll
> URL: http://llvm.org/viewvc/llvm-project/polly/trunk/test/Isl/CodeGen/inner_scev.ll?rev=244903&view=auto
> ==============================================================================
> --- polly/trunk/test/Isl/CodeGen/inner_scev.ll (added)
> +++ polly/trunk/test/Isl/CodeGen/inner_scev.ll Thu Aug 13 10:53:53 2015
> @@ -0,0 +1,50 @@
> +; RUN: opt %loadPolly -S -polly-no-early-exit -polly-detect-unprofitable -polly-codegen < %s
> +;
> +; Excerpt from the test-suite's oggenc reduced using bugpoint.
> +;
> +; It features a SCEV value using %div44 for the inner loop (for.body.51 =>
> +; for.cond.60.preheader) that is computed within the body of the outer loop
> +; (for.cond.30.preheader => for.cond.60.preheader). CodeGenerator would add a
> +; computation of the SCEV to before the scop that references %div44, which is
> +; not available then.
> +;
> +; XFAIL: *
> +;
> +; ModuleID = 'bugpoint-reduced-simplified.bc'
> +target triple = "x86_64-unknown-linux-gnu"
> +
> +define void @_vorbis_apply_window(float* %d) {
> +entry:
> +  %0 = load float*, float** undef, align 8
> +  %div23.neg = sdiv i64 0, -4
> +  %sub24 = add i64 0, %div23.neg
> +  br i1 undef, label %for.body, label %for.cond.30.preheader
> +
> +for.cond.30.preheader:                            ; preds = %for.body, %entry
> +  %sext = shl i64 %sub24, 32
> +  %conv48.74 = ashr exact i64 %sext, 32
> +  %cmp49.75 = icmp slt i64 %conv48.74, 0
> +  br i1 %cmp49.75, label %for.body.51.lr.ph, label %for.cond.60.preheader
> +
> +for.body:                                         ; preds = %for.body, %entry
> +  br i1 false, label %for.body, label %for.cond.30.preheader
> +
> +for.body.51.lr.ph:                                ; preds = %for.cond.30.preheader
> +  %div44 = sdiv i64 0, 2
> +  %sub45 = add nsw i64 %div44, 4294967295
> +  %1 = trunc i64 %sub45 to i32
> +  %2 = sext i32 %1 to i64
> +  br label %for.body.51
> +
> +for.cond.60.preheader:                            ; preds = %for.body.51, %for.cond.30.preheader
> +  ret void
> +
> +for.body.51:                                      ; preds = %for.body.51, %for.body.51.lr.ph
> +  %indvars.iv86 = phi i64 [ %2, %for.body.51.lr.ph ], [ undef, %for.body.51 ]
> +  %arrayidx53 = getelementptr inbounds float, float* %0, i64 %indvars.iv86
> +  %3 = load float, float* %arrayidx53, align 4
> +  %arrayidx55 = getelementptr inbounds float, float* %d, i64 0
> +  %mul56 = fmul float %3, undef
> +  store float %mul56, float* %arrayidx55, align 4
> +  br i1 false, label %for.body.51, label %for.cond.60.preheader
> +}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-commits


More information about the llvm-commits mailing list