[llvm] [SLP]Support LShr as base for copyable elements (PR #153393)

Alexander Kornienko via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 9 01:39:02 PDT 2025


alexfh wrote:

> We see another crash in SLP vectorizer after this commit, which reproduces also after [d0ea176](https://github.com/llvm/llvm-project/commit/d0ea176ccea8bdcd60aacc2753734294b9eec71f):
> 
> ```
> assert.h assertion failed at llvm/lib/Transforms/Vectorize/SLPVectorizer.cpp:20860 in auto llvm::slpvectorizer::BoUpSLP::BlockScheduling::tryScheduleBundle(ArrayRef<Value *>, BoUpSLP *, const InstructionsState &, const EdgeInfo &)::(anonymous class)::operator()(bool, ScheduleBundle &) const: Picked->isReady() && "must be ready to schedule"
> *** Check failure stack trace: ***                                                                                                                                                                                                                       @     0x55a81b288a24  absl::log_internal::LogMessage::SendToLog()                                                                                                                                                                                    @     0x55a81b2889d8  absl::log_internal::LogMessage::Flush()
>     @     0x55a81b4fea04  __assert_fail                                                                                                                                                                                                                  @     0x55a81a0bab9b  llvm::slpvectorizer::BoUpSLP::BlockScheduling::tryScheduleBundle()::$_1::operator()()                                                                                                                                          @     0x55a81a0323a6  llvm::slpvectorizer::BoUpSLP::buildTreeRec()
>     @     0x55a81a04b64f  llvm::slpvectorizer::BoUpSLP::transformNodes()                                                                                                                                                                                 @     0x55a81a0887ce  llvm::SLPVectorizerPass::vectorizeStoreChain()
>     @     0x55a81a08a974  llvm::SLPVectorizerPass::vectorizeStores()::$_0::operator()()                                                                                                                                                                  @     0x55a81a08998b  llvm::SLPVectorizerPass::vectorizeStores()
>     @     0x55a81a084ef9  llvm::SLPVectorizerPass::vectorizeStoreChains()                                                                                                                                                                                @     0x55a81a083270  llvm::SLPVectorizerPass::runImpl()
>     @     0x55a81a0827fd  llvm::SLPVectorizerPass::run()                                                                                                                                                                                                 @     0x55a81af32519  llvm::PassManager<>::run()
>     @     0x55a81af34f5d  llvm::ModuleToFunctionPassAdaptor::run()                                                                                                                                                                                       @     0x55a81af318d9  llvm::PassManager<>::run()
>     @     0x55a8158620b0  (anonymous namespace)::EmitAssemblyHelper::RunOptimizationPipeline()                                                                                                                                                           @     0x55a815858664  clang::emitBackendOutput()
>     @     0x55a815532338  clang::CodeGenAction::ExecuteAction()                                                                                                                                                                                          @     0x55a8160fa6ca  clang::FrontendAction::Execute()
>     @     0x55a81607576d  clang::CompilerInstance::ExecuteAction()                                                                                                                                                                                       @     0x55a81552bfbf  clang::ExecuteCompilerInvocation()
>     @     0x55a81552012f  cc1_main()
>     @     0x55a81551d4d6  ExecuteCC1Tool()
>     @     0x55a816226a1e  llvm::function_ref<>::callback_fn<>()
>     @     0x55a81b0eb259  llvm::CrashRecoveryContext::RunSafely()
>     @     0x55a816225f24  clang::driver::CC1Command::Execute()
>     @     0x55a8161e75d3  clang::driver::Compilation::ExecuteCommand()
>     @     0x55a8161e784f  clang::driver::Compilation::ExecuteJobs()                                                                                                                                                                                      @     0x55a816201760  clang::driver::Driver::ExecuteCompilation()
>     @     0x55a81551cbcb  clang_main()                                                                                                                                                                                                                   @     0x55a81551b274  main
> ```
> 
> The test case is being reduced.

The test case is https://gcc.godbolt.org/z/KP3hrYsnc (reduced from https://github.com/supranational/blst/blob/master/src/server.c).

```
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 void @blst_p2s_to_affine() {
  call void @POINTonE2s_to_affine()
  ret void
}

define internal void @POINTonE2s_to_affine() {
  %1 = alloca [2 x [12 x i32]], align 16
  br label %2

2:                                                ; preds = %6, %0
  %.0 = phi i64 [ 1, %0 ], [ %7, %6 ]
  %.not = icmp eq i64 %.0, 0
  br i1 %.not, label %8, label %3

3:                                                ; preds = %5, %2
  %4 = phi i1 [ false, %5 ], [ true, %2 ]
  br i1 %4, label %5, label %6

5:                                                ; preds = %3
  call void @sqr_fp2(ptr %1)
  br label %3

6:                                                ; preds = %3
  call void @sqr_fp2(ptr %1)
  %7 = add i64 %.0, 1
  br label %2

8:                                                ; preds = %2
  ret void
}

define void @mul_mont_n(ptr %0, ptr %1, ptr %2, ptr %3, i64 %4) {
  %6 = alloca i32, i64 %4, align 16
  %7 = load i32, ptr %0, align 4
  br label %8

8:                                                ; preds = %10, %5
  %.049 = phi i64 [ 0, %5 ], [ 1, %10 ]
  %.047 = phi i64 [ 0, %5 ], [ %16, %10 ]
  %9 = icmp ult i64 %.047, %4
  br i1 %9, label %10, label %17

10:                                               ; preds = %8
  %11 = load i32, ptr %1, align 4
  %12 = zext i32 %11 to i64
  %13 = mul i64 %4, %12
  %14 = or i64 %13, %.049
  %15 = trunc i64 %14 to i32
  store i32 %15, ptr %2, align 4
  %16 = add i64 %.047, 1
  br label %8

17:                                               ; preds = %8
  %.pre = load i32, ptr %0, align 4
  br label %18

18:                                               ; preds = %32, %17
  %.050 = phi i32 [ %7, %17 ], [ %31, %32 ]
  %.0 = phi i64 [ 0, %17 ], [ %28, %32 ]
  %19 = zext i32 %.050 to i64
  %20 = zext i32 %.pre to i64
  %21 = mul i64 %19, %20
  %22 = or i64 %21, %4
  %23 = lshr i64 %22, 1
  %24 = load i32, ptr %3, align 4
  %25 = trunc i64 %23 to i32
  %26 = or i32 %24, %25
  %27 = or i32 %26, 1
  store i32 %27, ptr %1, align 4
  %28 = add i64 %.0, 1
  %29 = icmp eq i64 %.0, %4
  br i1 %29, label %40, label %30

30:                                               ; preds = %18
  %31 = load i32, ptr %0, align 4
  br label %32

32:                                               ; preds = %34, %30
  %.1 = phi i64 [ 0, %30 ], [ %39, %34 ]
  %33 = icmp ult i64 %.1, %4
  br i1 %33, label %34, label %18

34:                                               ; preds = %32
  %35 = getelementptr i32, ptr %1, i64 %.1
  %36 = load i32, ptr %35, align 4
  %37 = or i32 %36, 1
  %38 = getelementptr i32, ptr %6, i64 %.1
  store i32 %37, ptr %38, align 4
  %39 = add i64 %.1, 1
  br label %32

40:                                               ; preds = %42, %18
  %.051 = phi i32 [ 1, %42 ], [ 0, %18 ]
  %.2 = phi i64 [ %46, %42 ], [ 0, %18 ]
  %41 = icmp ult i64 %.2, %4
  br i1 %41, label %42, label %47

42:                                               ; preds = %40
  %43 = load i32, ptr %2, align 4
  %44 = or i32 %.051, %43
  %45 = sub i32 0, %44
  store i32 %45, ptr %0, align 4
  %46 = add i64 %.2, 1
  br label %40

47:                                               ; preds = %40
  %48 = call i32 asm sideeffect "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 0)
  br label %49

49:                                               ; preds = %51, %47
  %.3 = phi i64 [ 0, %47 ], [ %60, %51 ]
  %50 = icmp ult i64 %.3, %4
  br i1 %50, label %51, label %61

51:                                               ; preds = %49
  %52 = load i32, ptr %0, align 4
  %53 = xor i32 %48, -1
  %54 = and i32 %52, %53
  %55 = getelementptr i32, ptr %6, i64 %.3
  %56 = load i32, ptr %55, align 4
  %57 = and i32 %56, %48
  %58 = or i32 %54, %57
  %59 = getelementptr i32, ptr %0, i64 %.3
  store i32 %58, ptr %59, align 4
  %60 = add i64 %.3, 1
  br label %49

61:                                               ; preds = %49
  ret void
}

define void @mul_mont_384(ptr %0) {
  call void @mul_mont_n(ptr %0, ptr %0, ptr %0, ptr %0, i64 12)
  ret void
}

define void @add_mod_n(ptr %0, ptr %1, ptr %2, i64 %3) {
  %5 = alloca i32, i64 %3, align 16
  br label %6

6:                                                ; preds = %8, %4
  %.032 = phi i64 [ 0, %4 ], [ %19, %8 ]
  %.0 = phi i64 [ 0, %4 ], [ %20, %8 ]
  %7 = icmp ult i64 %.0, %3
  br i1 %7, label %8, label %21

8:                                                ; preds = %6
  %9 = getelementptr i32, ptr %1, i64 %.0
  %10 = load i32, ptr %9, align 4
  %11 = zext i32 %10 to i64
  %12 = getelementptr i32, ptr %2, i64 %.0
  %13 = load i32, ptr %12, align 4
  %14 = zext i32 %13 to i64
  %15 = add i64 %.032, %14
  %16 = add i64 %15, %11
  %17 = trunc i64 %16 to i32
  %18 = getelementptr i32, ptr %5, i64 %.0
  store i32 %17, ptr %18, align 4
  %19 = lshr i64 %16, 32
  %20 = add i64 %.0, 1
  br label %6

21:                                               ; preds = %23, %6
  %.031 = phi i64 [ %30, %23 ], [ 0, %6 ]
  %.1 = phi i64 [ %31, %23 ], [ 0, %6 ]
  %22 = icmp ult i64 %.1, %3
  br i1 %22, label %23, label %32

23:                                               ; preds = %21
  %24 = getelementptr i32, ptr %5, i64 %.1
  %25 = load i32, ptr %24, align 4
  %26 = zext i32 %25 to i64
  %.neg = xor i64 %.031, -1
  %27 = add i64 %.neg, %26
  %28 = trunc i64 %27 to i32
  %29 = getelementptr i32, ptr %0, i64 %.1
  store i32 %28, ptr %29, align 4
  %30 = lshr i64 %27, 1
  %31 = add i64 %.1, 1
  br label %21

32:                                               ; preds = %21
  %33 = call i32 asm sideeffect "", "=r,0,~{dirflag},~{fpsr},~{flags}"(i32 0)
  br label %34

34:                                               ; preds = %36, %32
  %.2 = phi i64 [ 0, %32 ], [ %44, %36 ]
  %35 = icmp ult i64 %.2, %3
  br i1 %35, label %36, label %45

36:                                               ; preds = %34
  %37 = getelementptr i32, ptr %0, i64 %.2
  %38 = load i32, ptr %37, align 4
  %39 = and i32 %38, -2
  %40 = getelementptr i32, ptr %5, i64 %.2
  %41 = load i32, ptr %40, align 4
  %42 = and i32 %41, %33
  %43 = or i32 %39, %42
  store i32 %43, ptr %37, align 4
  %44 = add i64 %.2, 1
  br label %34

45:                                               ; preds = %34
  ret void
}

define void @add_mod_384(ptr %0, ptr %1) {
  call void @add_mod_n(ptr %0, ptr %1, ptr %0, i64 12)
  ret void
}

define void @sqr_mont_384x(ptr %0) {
  %2 = getelementptr inbounds i8, ptr %0, i64 48
  call void @mul_mont_384(ptr %2)
  call void @add_mod_384(ptr %2, ptr %2)
  ret void
}

define void @sqr_fp2(ptr %0) {
  call void @sqr_mont_384x(ptr %0)
  ret void
}

; uselistorder directives
uselistorder ptr @sqr_fp2, { 1, 0 }
```

https://github.com/llvm/llvm-project/pull/153393


More information about the llvm-commits mailing list