[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