Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

opt hangs in LoadStoreVectorizer #37865

Open
uabjean opened this issue Aug 10, 2018 · 3 comments · Fixed by #104815
Open

opt hangs in LoadStoreVectorizer #37865

uabjean opened this issue Aug 10, 2018 · 3 comments · Fixed by #104815
Labels
bugzilla Issues migrated from bugzilla hang Compiler hang (infinite loop) vectorizers

Comments

@uabjean
Copy link
Collaborator

uabjean commented Aug 10, 2018

Bugzilla Link 38517
Version trunk
OS Linux
Attachments reproducer with nested load
CC @bevin-hansson,@mikaelholmen

Extended Description

Running
opt -load-store-vectorizer -o tmp.opt.ll tmp.ll
with the attached reproducer, the LoadStoreVectorizer hangs in an endless loop.

The originating src program consists of a nested load, where the inner load's result is used for indexing the outer load.

A somewhat shallow analysis by me indicates that the areConsecutivePointers() function do some SCEV magic to find that the pointers for these loads are consecutive, but it doesn't seem to me that they are. Then when vectorization has been performed, the IR references has a loop, and when the reorder() function is applied to it, it follows that loop endlessly.

This is the original c-program for reference:

#include <stdint.h>

uint32_t a = 0;
uint32_t b[1][3] = { { 0, 0, 0 } };
const uint16_t c = 1;

int main() {
b[(2u & b[a % 1][2u % 3]) % 1][c % 3];
}

@mikaelholmen
Copy link
Collaborator

Patch suggestion: https://reviews.llvm.org/D54468

@llvmbot
Copy link
Member

llvmbot commented Feb 16, 2019

Based on the patch above, a few more reproducers to increase the coverage of the problem:

target triple = "aarch64"

; Function Attrs: noinline nounwind
define i32 @​test([2 x i32]* %array) #​0 {
entry:
%arrayidx = getelementptr inbounds [2 x i32], [2 x i32]* %array, i32 0, i32 1
%t = load i32, i32* %arrayidx, align 4
%rem = urem i32 %t, 1
%arrayidx2 = getelementptr inbounds [2 x i32], [2 x i32]* %array, i32 %rem, i32 0
%v = load i32, i32* %arrayidx2, align 4
%r = add i32 %v, %t
ret i32 %r
}

attributes #​0 = { noinline nounwind }

target triple = "aarch64"

; Function Attrs: noinline nounwind
define i32 @​test([2 x i32]* %array, i32 %idx) #​0 {
entry:
%ptr1 = getelementptr inbounds [2 x i32], [2 x i32]* %array, i32 %idx, i32 1
%t = load i32, i32* %ptr1, align 4
%t2 = mul i32 %t, 2
%idx.p.2t = add i32 %idx, %t2
%idx.p.t = sub i32 %idx.p.2t, %t
%idx.another = sub i32 %idx.p.t, %t
%ptr0 = getelementptr inbounds [2 x i32], [2 x i32]* %array, i32 %idx.another, i32 0
%v = load i32, i32* %ptr0, align 4
%r = add i32 %v, %t
ret i32 %r
}

attributes #​0 = { noinline nounwind }

target triple = "aarch64"

; Function Attrs: noinline nounwind
define i32 @​test(i32* %array, i32 %idx, i1 %cond, i1 %cond2) #​0 {
entry:
%idx.p.7 = add nsw i32 %idx, 7
%idx.p.7.sext = sext i32 %idx.p.7 to i64
%ptr1.dummy = getelementptr inbounds i32, i32* %array, i64 21
%ptr1.true = getelementptr inbounds i32, i32* %array, i64 1
%ptr1.false = getelementptr inbounds i32, i32* %array, i64 %idx.p.7.sext
%ptr1.tmp = select i1 %cond, i32* %ptr1.true, i32* %ptr1.false
%ptr1 = select i1 %cond2, i32* %ptr1.tmp, i32* %ptr1.dummy
%t = load i32, i32* %ptr1, align 4
%t2 = mul i32 %t, 2
%idx.p.2t = add i32 %idx, %t2
%idx.p.t = sub i32 %idx.p.2t, %t
%idx.another = sub i32 %idx.p.t, %t
%idx.p.6 = add i32 %idx.another, 6
%idx.p.6.sext = sext i32 %idx.p.6 to i64
%ptr0.dummy = getelementptr inbounds i32, i32* %array, i64 20
%ptr0.true = getelementptr inbounds i32, i32* %array, i64 0
%ptr0.false = getelementptr inbounds i32, i32* %array, i64 %idx.p.6.sext
%ptr0.tmp = select i1 %cond, i32* %ptr0.true, i32* %ptr0.false
%ptr0 = select i1 %cond2, i32* %ptr0.tmp, i32* %ptr0.dummy
%v = load i32, i32* %ptr0, align 4
%r = add i32 %v, %t
ret i32 %r
}

attributes #​0 = { noinline nounwind }

Please see https://reviews.llvm.org/D54468#1395738 for details.

@llvmbot llvmbot transferred this issue from llvm/llvm-bugzilla-archive Dec 10, 2021
artagnon added a commit to artagnon/llvm-project that referenced this issue Aug 8, 2024
LoadStoreVectorizer hangs on certain examples, when its reorder function
goes into a cycle. Detect this cycle and explicitly forbid it, using an
assert, and document the resulting crash in a test-case under AArch64.
artagnon added a commit that referenced this issue Aug 9, 2024
LoadStoreVectorizer hangs on certain examples, when its reorder function
goes into a cycle. Detect this cycle and explicitly forbid it, using an
assert, and document the resulting crash in a test-case under AArch64.
artagnon added a commit to artagnon/llvm-project that referenced this issue Aug 9, 2024
This reverts commit 199d6f2, as there is a buildbot failure.
artagnon added a commit to artagnon/llvm-project that referenced this issue Aug 9, 2024
Follow up on 199d6f2 (LSV: document hang reported in llvm#37865) to fix the
build when omitting the AArch64 target. Add the missing lit.local.cfg.
artagnon added a commit that referenced this issue Aug 9, 2024
Follow up on 199d6f2 (LSV: document hang reported in #37865) to fix the
build when omitting the AArch64 target. Add the missing lit.local.cfg.
kutemeikito added a commit to kutemeikito/llvm-project that referenced this issue Aug 10, 2024
* 'main' of https://github.com/llvm/llvm-project: (700 commits)
  [SandboxIR][NFC] SingleLLVMInstructionImpl class (llvm#102687)
  [ThinLTO]Clean up 'import-assume-unique-local' flag. (llvm#102424)
  [nsan] Make #include more conventional
  [SandboxIR][NFC] Use Tracker.emplaceIfTracking()
  [libc]  Moved range_reduction_double ifdef statement (llvm#102659)
  [libc] Fix CFP long double and add tests (llvm#102660)
  [TargetLowering] Handle vector types in expandFixedPointMul (llvm#102635)
  [compiler-rt][NFC] Replace environment variable with %t (llvm#102197)
  [UnitTests] Convert a test to use opaque pointers (llvm#102668)
  [CodeGen][NFCI] Don't re-implement parts of ASTContext::getIntWidth (llvm#101765)
  [SandboxIR] Clean up tracking code with the help of emplaceIfTracking() (llvm#102406)
  [mlir][bazel] remove extra blanks in mlir-tblgen test
  [NVPTX][NFC] Update tests to use bfloat type (llvm#101493)
  [mlir] Add support for parsing nested PassPipelineOptions (llvm#101118)
  [mlir][bazel] add missing td dependency in mlir-tblgen test
  [flang][cuda] Fix lib dependency
  [libc] Clean up remaining use of *_WIDTH macros in printf (llvm#102679)
  [flang][cuda] Convert cuf.alloc for box to fir.alloca in device context (llvm#102662)
  [SandboxIR] Implement the InsertElementInst class (llvm#102404)
  [libc] Fix use of cpp::numeric_limits<...>::digits (llvm#102674)
  [mlir][ODS] Verify type constraints in Types and Attributes (llvm#102326)
  [LTO] enable `ObjCARCContractPass` only on optimized build  (llvm#101114)
  [mlir][ODS] Consistent `cppType` / `cppClassName` usage (llvm#102657)
  [lldb] Move definition of SBSaveCoreOptions dtor out of header (llvm#102539)
  [libc] Use cpp::numeric_limits in preference to C23 <limits.h> macros (llvm#102665)
  [clang] Implement -fptrauth-auth-traps. (llvm#102417)
  [LLVM][rtsan] rtsan transform to preserve CFGAnalyses (llvm#102651)
  Revert "[AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)"
  [RISCV][GISel] Add missing tests for G_CTLZ/CTTZ instruction selection. NFC
  Return available function types for BindingDecls. (llvm#102196)
  [clang] Wire -fptrauth-returns to "ptrauth-returns" fn attribute. (llvm#102416)
  [RISCV] Remove riscv-experimental-rv64-legal-i32. (llvm#102509)
  [RISCV] Move PseudoVSET(I)VLI expansion to use PseudoInstExpansion. (llvm#102496)
  [NVPTX] support switch statement with brx.idx (reland) (llvm#102550)
  [libc][newhdrgen]sorted function names in yaml (llvm#102544)
  [GlobalIsel] Combine G_ADD and G_SUB with constants (llvm#97771)
  Suppress spurious warnings due to R_RISCV_SET_ULEB128
  [scudo] Separated committed and decommitted entries. (llvm#101409)
  [MIPS] Fix missing ANDI optimization (llvm#97689)
  [Clang] Add env var for nvptx-arch/amdgpu-arch timeout (llvm#102521)
  [asan] Switch allocator to dynamic base address (llvm#98511)
  [AMDGPU] Move `AMDGPUAttributorPass` to full LTO post link stage (llvm#102086)
  [libc][math][c23] Add fadd{l,f128} C23 math functions (llvm#102531)
  [mlir][bazel] revert bazel rule change for DLTITransformOps
  [msan] Support vst{2,3,4}_lane instructions (llvm#101215)
  Revert "[MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)"
  [X86] pr57673.ll - generate MIR test checks
  [mlir][vector][test] Split tests from vector-transfer-flatten.mlir (llvm#102584)
  [mlir][bazel] add bazel rule for DLTITransformOps
  OpenMPOpt: Remove dead include
  [IR] Add method to GlobalVariable to change type of initializer. (llvm#102553)
  [flang][cuda] Force default allocator in device code (llvm#102238)
  [llvm] Construct SmallVector<SDValue> with ArrayRef (NFC) (llvm#102578)
  [MLIR][DLTI][Transform] Introduce transform.dlti.query (llvm#101561)
  [AMDGPU][AsmParser][NFC] Remove a misleading comment. (llvm#102604)
  [Arm][AArch64][Clang] Respect function's branch protection attributes. (llvm#101978)
  [mlir] Verifier: steal bit to track seen instead of set. (llvm#102626)
  [Clang] Fix Handling of Init Capture with Parameter Packs in LambdaScopeForCallOperatorInstantiationRAII (llvm#100766)
  [X86] Convert truncsat clamping patterns to use SDPatternMatch. NFC.
  [gn] Give two scripts argparse.RawDescriptionHelpFormatter
  [bazel] Add missing dep for the SPIRVToLLVM target
  [Clang] Simplify specifying passes via -Xoffload-linker (llvm#102483)
  [bazel] Port for d45de80
  [SelectionDAG] Use unaligned store/load to move AVX registers onto stack for `insertelement` (llvm#82130)
  [Clang][OMPX] Add the code generation for multi-dim `num_teams` (llvm#101407)
  [ARM] Regenerate big-endian-vmov.ll. NFC
  [AMDGPU][AsmParser][NFCI] All NamedIntOperands to be of the i32 type. (llvm#102616)
  [libc][math][c23] Add totalorderl function. (llvm#102564)
  [mlir][spirv] Support `memref` in `convert-to-spirv` pass (llvm#102534)
  [MLIR][GPU-LLVM] Convert `gpu.func` to `llvm.func` (llvm#101664)
  Fix a unit test input file (llvm#102567)
  [llvm-readobj][COFF] Dump hybrid objects for ARM64X files. (llvm#102245)
  AMDGPU/NewPM: Port SIFixSGPRCopies to new pass manager (llvm#102614)
  [MemoryBuiltins] Simplify getCalledFunction() helper (NFC)
  [AArch64] Add invalid 1 x vscale costs for reductions and reduction-operations. (llvm#102105)
  [MemoryBuiltins] Handle allocator attributes on call-site
  LSV/test/AArch64: add missing lit.local.cfg; fix build (llvm#102607)
  Revert "Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)"
  [RISCV] Add Syntacore SCR5 RV32/64 processors definition (llvm#102285)
  [InstCombine] Remove unnecessary RUN line from test (NFC)
  [flang][OpenMP] Handle multiple ranges in `num_teams` clause (llvm#102535)
  [mlir][vector] Add tests for scalable vectors in one-shot-bufferize.mlir (llvm#102361)
  [mlir][vector] Disable `vector.matrix_multiply` for scalable vectors (llvm#102573)
  [clang] Implement CWG2627 Bit-fields and narrowing conversions (llvm#78112)
  [NFC] Use references to avoid copying (llvm#99863)
  Revert "[mlir][ArmSME] Pattern to swap shape_cast(tranpose) with transpose(shape_cast) (llvm#100731)" (llvm#102457)
  [IRBuilder] Generate nuw GEPs for struct member accesses (llvm#99538)
  [bazel] Port for 9b06e25
  [CodeGen][NewPM] Improve start/stop pass error message CodeGenPassBuilder (llvm#102591)
  [AArch64] Implement TRBMPAM_EL1 system register (llvm#102485)
  [InstCombine] Fixing wrong select folding in vectors with undef elements (llvm#102244)
  [AArch64] Sink operands to fmuladd. (llvm#102297)
  LSV: document hang reported in llvm#37865 (llvm#102479)
  Enable logf128 constant folding for hosts with 128bit floats (llvm#96287)
  [RISCV][clang] Remove bfloat base type in non-zvfbfmin vcreate (llvm#102146)
  [RISCV][clang] Add missing `zvfbfmin` to `vget_v` intrinsic (llvm#102149)
  [mlir][vector] Add mask elimination transform (llvm#99314)
  [Clang][Interp] Fix display of syntactically-invalid note for member function calls (llvm#102170)
  [bazel] Port for 3fffa6d
  [DebugInfo][RemoveDIs] Use iterator-inserters in clang (llvm#102006)
  ...

Signed-off-by: Edwiin Kusuma Jaya <kutemeikito0905@gmail.com>
artagnon added a commit to artagnon/llvm-project that referenced this issue Aug 19, 2024
Forbid zero SCEV diff in getConstantOffset, hence forbidding cycles
which would crash LoadStoreVectorizer when vectorizing.

Fixes llvm#37865.
@EugeneZelenko EugeneZelenko added hang Compiler hang (infinite loop) and removed llvm:optimizations labels Aug 22, 2024
cjdb pushed a commit to cjdb/llvm-project that referenced this issue Aug 23, 2024
Forbid load-load cycles which would crash LoadStoreVectorizer when
reordering instructions.

Fixes llvm#37865.
@artagnon
Copy link
Contributor

artagnon commented Sep 2, 2024

The fix has been reverted in 9671ed1 (#106245).

@artagnon artagnon reopened this Sep 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bugzilla Issues migrated from bugzilla hang Compiler hang (infinite loop) vectorizers
Projects
None yet
Development

Successfully merging a pull request may close this issue.

6 participants