Comment # 9 on bug 1204267 from
The rabbit hole is deep!

I noticed two oddities:

The bitcode triggers the error in llc-{13,14,15}, so it's not a change in LLVM.

I built Mesa 22.2.1 with LLVM14 (building old Mesa with LLVM15 does not work)
and the bitcode produced also triggers the error in llc-{13, 14, 15}. I built
Mesa 22.1.7 with LLVM14 as well and the bitcode also triggers the error!

So the difference has to be somewhere in how Mesa invokes LLVM. I added
LLVMPassBuilderOptionsSetDebugLogging(opts, true); to print the passes. Output
with Mesa 22.2.1 + LLVM 15:

ir_fs322_variant0.bc written
Invoke as "opt -sroa -early-cse -simplifycfg -reassociate -mem2reg -constprop
-instcombine -gvn ir_fs322_variant0.bc | llc -O2 [-mcpu=<-mcpu option>]
[-mattr=<-mattr option(s)>]"
Running pass: AlwaysInlinerPass on [module]
Running analysis: InnerAnalysisManagerProxy<llvm::FunctionAnalysisManager,
llvm::Module> on [module]
Running analysis: ProfileSummaryAnalysis on [module]
Running pass: CoroConditionalWrapper on [module]
Running pass: AnnotationRemarksPass on fs_variant_partial (1387 instructions)
Running analysis: TargetLibraryAnalysis on fs_variant_partial
LLVM ERROR: Cannot select: 0x10505b0: v4i32 = ARMISD::VCMPZ 0x1287c98,
Constant:i32<2>

Mesa with LLVM 14 did not output that at all, which was caused by this
conditional:

#if LLVM_VERSION_MAJOR >= 15
#define GALLIVM_HAVE_CORO 0
#define GALLIVM_USE_NEW_PASS 1
#elif LLVM_VERSION_MAJOR >= 8
#define GALLIVM_HAVE_CORO 1
#define GALLIVM_USE_NEW_PASS 0
#else
#define GALLIVM_HAVE_CORO 0
#define GALLIVM_USE_NEW_PASS 0
#endif

So with LLVM >= 15 it uses the new pass manager and everything is different.

Some experiments with opt + llc proved to be very helpful:

opt -passes=always-inline,instcombine ir_fs322_variant0.bc | llc -mcpu=generic
-> works
opt -passes=always-inline ir_fs322_variant0.bc | llc -mcpu=generic -> fails!

So the "instcombine" pass makes all the difference here to avoid the "Cannot
select" error.

Question is, why is the instcombine pass not used? Mesa hardcodes it in the
list of passes after all:

   if (!(gallivm_perf & GALLIVM_PERF_NO_OPT))
      strcpy(passes,
"sroa,early-cse,simplifycfg,reassociate,mem2reg,constprop,instcombine,");
   else
      strcpy(passes, "mem2reg");

   LLVMRunPasses(gallivm->module, passes,
LLVMGetExecutionEngineTargetMachine(gallivm->engine), opts);

opt can actually answer that quickly:

e06e5d2ccf7e:~/mesa/build # opt-15.0.2
-passes=sroa,early-cse,simplifycfg,reassociate,mem2reg,constprop,instcombine,
ir_fs322_variant0.bc | llc-14.0.6 -mcpu=generic
opt-15.0.2: unknown function pass 'constprop'
(failure)

Next try:

e06e5d2ccf7e:~/mesa/build # opt-15.0.2
-passes=sroa,early-cse,simplifycfg,reassociate,mem2reg,instcombine,
ir_fs322_variant0.bc | llc-14.0.6 -mcpu=generic
opt-15.0.2: unknown function pass ''
(failure)

Next try:

e06e5d2ccf7e:~/mesa/build # opt-15.0.2
-passes=sroa,early-cse,simplifycfg,reassociate,mem2reg,instcombine
ir_fs322_variant0.bc | llc-14.0.6 -mcpu=generic
        .text
        .syntax unified
(success!)

So the missing "instcombine" pass causes the "Cannot select" error and the pass
is missing
because Mesa passes an invalid list of passes to LLVMRunPasses and ignores the
error. This
means that if Mesa was built with LLVM >= 15, only the "default<O2>" passes
were actually run,
so the code was not really optimized...

With this patch, the "Cannot select" error is gone:

    if (!(gallivm_perf & GALLIVM_PERF_NO_OPT))
-      strcpy(passes,
"sroa,early-cse,simplifycfg,reassociate,mem2reg,constprop,instcombine,");
+      strcpy(passes,
"sroa,early-cse,simplifycfg,reassociate,mem2reg,instsimplify,instcombine");
    else
       strcpy(passes, "mem2reg");

I'll send that to mesa upstream.


You are receiving this mail because: