Skip to content

[SLPVectorizer] Assertion failure: "trying to erase instruction with users" in BoUpSLP destructor #172221

@saurabhk

Description

@saurabhk

Description

The SLP Vectorizer crashes with an assertion failure when vectorizing code containing a specific pattern of extractelement → fpext → fmul → select → fcmp chains.
The assertion I->use_empty() && "trying to erase instruction with users." fails in BoUpSLP::~BoUpSLP() because an extractelement instruction is marked for deletion but still has live users (an insertelement instruction that was not marked for deletion).

When assertions are disabled, this leads to a segfault in the VectorCombine pass.

Reproducer
Minimal LLVM IR (75 lines):

; Minimal reproducer for SLP Vectorizer assertion failure
; Run: opt -passes='slp-vectorizer' crash.ll -o /dev/null

target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128"
target triple = "x86_64-unknown-linux-gnu"

define i1 @slp_crash() {
entry:
  %e0 = extractelement <4 x float> splat (float 0.0), i64 0
  %c1 = fpext float %e0 to double
  %m1 = fmul double 0.0, %c1
  %s1 = select i1 false, double %m1, double 0.0
  %r1 = fcmp olt double %s1, 0.0

  %c2 = fpext float 0.0 to double
  %m2 = fmul double 0.0, %c2
  %s2 = select i1 false, double %m2, double 0.0
  %r2 = fcmp olt double %s2, 0.0

  %e1 = extractelement <4 x float> splat (float 1.0), i64 0
  %c3 = fpext float %e1 to double
  %m3 = fmul double 0.0, %c3
  %s3 = select i1 false, double %m3, double 0.0
  %r3 = fcmp olt double %s3, 0.0

  %e2 = extractelement <4 x float> splat (float 2.0), i64 0
  %c4 = fpext float %e2 to double
  %m4 = fmul double 0.0, %c4
  %s4 = select i1 false, double %m4, double 0.0
  %r4 = fcmp olt double %s4, 0.0

  %e3 = extractelement <4 x float> splat (float 3.0), i64 0
  %c5 = fpext float %e3 to double
  %m5 = fmul double 0.0, %c5
  %s5 = select i1 false, double %m5, double 0.0
  %r5 = fcmp olt double %s5, 0.0

  %e4 = extractelement <4 x float> splat (float 4.0), i64 0
  %c6 = fpext float %e4 to double
  %m6 = fmul double 0.0, %c6
  %s6 = select i1 false, double %m6, double 0.0
  %r6 = fcmp olt double %s6, 0.0

  %e5 = extractelement <4 x float> splat (float 5.0), i64 0
  %c7 = fpext float %e5 to double
  %m7 = fmul double 0.0, %c7
  %s7 = select i1 false, double %m7, double 0.0
  %r7 = fcmp olt double %s7, 0.0

  %m8 = fmul double 0.0, %c1
  %s8 = select i1 false, double %m8, double 0.0
  %r8 = fcmp olt double %s8, 0.0

  ret i1 %r8
}

Steps to Reproduce
opt -passes='slp-vectorizer' crash.ll -o /dev/null

Stack Trace

  llvm::slpvectorizer::BoUpSLP::~BoUpSLP(): 
  Assertion `I->use_empty() && "trying to erase instruction with users."' failed.

Stack dump:
0.  Program arguments: opt -passes=slp-vectorizer crash.ll -o /dev/null
1.  Running pass "function(slp-vectorizer)" on module "crash.ll"
2.  Running pass "slp-vectorizer" on function "slp_crash"
 #9  llvm::slpvectorizer::BoUpSLP::~BoUpSLP()
#10  llvm::SLPVectorizerPass::runImpl(...)
#11  llvm::SLPVectorizerPass::run(...)

Environment
LLVM version: trunk (commit 96891b7)
Target: x86_64-unknown-linux-gnu

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions