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.
46 lines
1.7 KiB
LLVM
46 lines
1.7 KiB
LLVM
; RUN: opt %loadNPMPolly -passes=polly-codegen -S \
|
|
; RUN: -polly-invariant-load-hoisting=true < %s | FileCheck %s
|
|
;
|
|
; CHECK: entry:
|
|
; CHECK-NEXT: %outvalue.141.phiops = alloca i64
|
|
; CHECK-NEXT: %.preload.s2a = alloca i8
|
|
; CHECK-NEXT: %umax = call i32 @llvm.umax.i32(i32 undef, i32 1)
|
|
; CHECK-NEXT: %divpolly = sdiv i32 undef, %umax
|
|
; CHECK-NEXT: %div = sdiv i32 undef, undef
|
|
;
|
|
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
|
|
|
|
; Function Attrs: nounwind uwtable
|
|
define void @int_downsample() #0 {
|
|
entry:
|
|
%div = sdiv i32 undef, undef
|
|
br label %for.cond10.preheader.lr.ph
|
|
|
|
for.cond10.preheader.lr.ph: ; preds = %entry
|
|
br label %for.body17.lr.ph
|
|
|
|
for.body17.lr.ph: ; preds = %for.end22, %for.cond10.preheader.lr.ph
|
|
%outcol_h.048 = phi i32 [ 0, %for.cond10.preheader.lr.ph ], [ %add31, %for.end22 ]
|
|
%0 = load ptr, ptr undef
|
|
%idx.ext = zext i32 %outcol_h.048 to i64
|
|
%add.ptr = getelementptr inbounds i8, ptr %0, i64 %idx.ext
|
|
br label %for.body17
|
|
|
|
for.body17: ; preds = %for.body17, %for.body17.lr.ph
|
|
%outvalue.141 = phi i64 [ poison, %for.body17.lr.ph ], [ %add19, %for.body17 ]
|
|
%inptr.040 = phi ptr [ %add.ptr, %for.body17.lr.ph ], [ poison, %for.body17 ]
|
|
%1 = load i8, ptr %inptr.040
|
|
%add19 = mul nsw i64 0, %outvalue.141
|
|
br i1 false, label %for.body17, label %for.end22
|
|
|
|
for.end22: ; preds = %for.body17
|
|
%add31 = add i32 %outcol_h.048, %div
|
|
br i1 undef, label %for.body17.lr.ph, label %for.end32
|
|
|
|
for.end32: ; preds = %for.end22
|
|
br label %for.end36
|
|
|
|
for.end36: ; preds = %for.end32
|
|
ret void
|
|
}
|