See the following case:
```
@GlobIntONE = global i32 0, align 4
define ptr @src() {
entry:
br label %for.body.peel.begin
for.body.peel.begin: ; preds = %entry
br label %for.body.peel
for.body.peel: ; preds = %for.body.peel.begin
br i1 true, label %cleanup.peel, label %cleanup.loopexit.peel
cleanup.loopexit.peel: ; preds = %for.body.peel
br label %cleanup.peel
cleanup.peel: ; preds = %cleanup.loopexit.peel, %for.body.peel
%retval.2.peel = phi ptr [ undef, %for.body.peel ], [ @GlobIntONE, %cleanup.loopexit.peel ]
br i1 true, label %for.body.peel.next, label %cleanup7
for.body.peel.next: ; preds = %cleanup.peel
br label %for.body.peel.next1
for.body.peel.next1: ; preds = %for.body.peel.next
br label %entry.peel.newph
entry.peel.newph: ; preds = %for.body.peel.next1
br label %for.body
for.body: ; preds = %cleanup, %entry.peel.newph
%retval.0 = phi ptr [ %retval.2.peel, %entry.peel.newph ], [ %retval.2, %cleanup ]
br i1 false, label %cleanup, label %cleanup.loopexit
cleanup.loopexit: ; preds = %for.body
br label %cleanup
cleanup: ; preds = %cleanup.loopexit, %for.body
%retval.2 = phi ptr [ %retval.0, %for.body ], [ @GlobIntONE, %cleanup.loopexit ]
br i1 false, label %for.body, label %cleanup7.loopexit
cleanup7.loopexit: ; preds = %cleanup
%retval.2.lcssa.ph = phi ptr [ %retval.2, %cleanup ]
br label %cleanup7
cleanup7: ; preds = %cleanup7.loopexit, %cleanup.peel
%retval.2.lcssa = phi ptr [ %retval.2.peel, %cleanup.peel ], [ %retval.2.lcssa.ph, %cleanup7.loopexit ]
ret ptr %retval.2.lcssa
}
define ptr @tgt() {
entry:
br label %for.body.peel.begin
for.body.peel.begin: ; preds = %entry
br label %for.body.peel
for.body.peel: ; preds = %for.body.peel.begin
br i1 true, label %cleanup.peel, label %cleanup.loopexit.peel
cleanup.loopexit.peel: ; preds = %for.body.peel
br label %cleanup.peel
cleanup.peel: ; preds = %cleanup.loopexit.peel, %for.body.peel
%retval.2.peel = phi ptr [ undef, %for.body.peel ], [ @GlobIntONE, %cleanup.loopexit.peel ]
br i1 true, label %for.body.peel.next, label %cleanup7
for.body.peel.next: ; preds = %cleanup.peel
br label %for.body.peel.next1
for.body.peel.next1: ; preds = %for.body.peel.next
br label %entry.peel.newph
entry.peel.newph: ; preds = %for.body.peel.next1
br label %for.body
for.body: ; preds = %cleanup, %entry.peel.newph
br i1 false, label %cleanup, label %cleanup.loopexit
cleanup.loopexit: ; preds = %for.body
br label %cleanup
cleanup: ; preds = %cleanup.loopexit, %for.body
br i1 false, label %for.body, label %cleanup7.loopexit
cleanup7.loopexit: ; preds = %cleanup
%retval.2.lcssa.ph = phi ptr [ %retval.2.peel, %cleanup ]
br label %cleanup7
cleanup7: ; preds = %cleanup7.loopexit, %cleanup.peel
%retval.2.lcssa = phi ptr [ %retval.2.peel, %cleanup.peel ], [ %retval.2.lcssa.ph, %cleanup7.loopexit ]
ret ptr %retval.2.lcssa
}
```
1. `simplifyInstruction(%retval.2.peel)` returns `@GlobIntONE`. Thus,
`ScalarEvolution::createNodeForPHI` returns SCEV expr `@GlobIntONE` for
`%retval.2.peel`.
2. `SimplifyIndvar::replaceIVUserWithLoopInvariant` tries to replace the
use of `%retval.2.peel` in `%retval.2.lcssa.ph` with `@GlobIntONE`.
3. `simplifyLoopAfterUnroll -> simplifyLoopIVs -> SCEVExpander::expand`
reuses `%retval.2.peel = phi ptr [ undef, %for.body.peel ], [
@GlobIntONE, %cleanup.loopexit.peel ]` to generate code for
`@GlobIntONE`. It is incorrect.
This patch disallows simplifying `phi(undef, X)` to `X` by setting
`CanUseUndef` to false.
Closes https://github.com/llvm/llvm-project/issues/114879.
61 lines
2.5 KiB
LLVM
61 lines
2.5 KiB
LLVM
; RUN: opt %loadNPMPolly '-passes=print<polly-function-scops>' -disable-output < %s 2>&1 | FileCheck %s
|
|
|
|
; Derived from test-suite/SingleSource/UnitTests/Vector/SSE/sse.stepfft.c
|
|
|
|
; The values %mul.i44 is simplified to constant 4 by ScalarEvolution, but
|
|
; SCEVAffinator used to check whether the sdiv's argument was constant.
|
|
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
target triple = "x86_64-unknown-linux-gnu"
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define void @cfft2(i32 %n, ptr %A) local_unnamed_addr #0 {
|
|
entry:
|
|
br i1 true, label %for.body.lr.ph, label %for.end
|
|
|
|
for.body.lr.ph: ; preds = %entry
|
|
br label %for.body
|
|
|
|
for.body: ; preds = %for.inc, %for.body.lr.ph
|
|
%mj.017 = phi i32 [ 1, %for.body.lr.ph ], [ poison, %for.inc ]
|
|
br i1 true, label %if.else, label %if.then
|
|
|
|
if.then: ; preds = %for.body
|
|
br label %for.inc
|
|
|
|
if.else: ; preds = %for.body
|
|
%mul.i44 = shl i32 %mj.017, 2
|
|
%div.i45 = sdiv i32 %n, %mul.i44
|
|
br i1 true, label %for.body.i58.lr.ph, label %for.inc
|
|
|
|
for.body.i58.lr.ph: ; preds = %if.else
|
|
br i1 false, label %for.body.i58.us, label %for.body.i58.preheader
|
|
|
|
for.body.i58.preheader: ; preds = %for.body.i58.lr.ph
|
|
br label %for.body.i58
|
|
|
|
for.body.i58.us: ; preds = %for.body.i58.us, %for.body.i58.lr.ph
|
|
br i1 false, label %for.inc, label %for.body.i58.us
|
|
|
|
for.body.i58: ; preds = %for.body.i58, %for.body.i58.preheader
|
|
store double 0.0, ptr %A
|
|
%exitcond42 = icmp eq i32 0, %div.i45
|
|
br i1 %exitcond42, label %for.inc, label %for.body.i58
|
|
|
|
for.inc: ; preds = %for.body.i58, %for.body.i58.us, %if.else, %if.then
|
|
br i1 undef, label %for.end, label %for.body
|
|
|
|
for.end: ; preds = %for.inc, %entry
|
|
ret void
|
|
}
|
|
|
|
attributes #0 = { nounwind uwtable "disable-tail-calls"="false" "less-precise-fpmad"="false" "frame-pointer"="none" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" }
|
|
|
|
!llvm.ident = !{!0}
|
|
|
|
!0 = !{!"clang version 3.9.0 (trunk 273249) (llvm/trunk 273255)"}
|
|
|
|
; CHECK-LABEL: Stmt_for_body_i58
|
|
; CHECK-NEXT: Domain :=
|
|
; CHECK-NEXT: [n] -> { Stmt_for_body_i58[0] : -3 <= n <= 3 };
|