数学ライブラリに関するLLVM 8以降のORC JITの問題 -- llvm フィールド と jit フィールド と llvm-ir フィールド 関連 問題

LLVM 8 and later ORC JIT problems with math library












1
vote

問題

日本語

LLVM 8(現在のLLVMトランク、AKA LLVM 9を含む)標準数学ライブラリへの呼び出しを含むORC JIT ExecutionEngineを使用すると、問題が発生します。

JITコンパイラは関数のシンボルを見つけることができますが、関数が数学ライブラリに電話をかける場合にはアドレスを取得できません。

問題を示す簡単な悪用を添付します。 Program Test.ccは、LLVMの中間表現で単一の機能を含むIRファイルを読み込みます。 この関数は単一の引数、浮動小数点数、および

の場合の戻り値を取ります。
  • "func_works.ll"引数自体、
  • の場合
  • "func_cos_fails.ll"引数の余弦。

実行時に2つのファイルの間の選択を実装していないため、他の場合に切り替えるとプログラムを再構築する必要があります。

プログラムは、LLVMに付属の標準のKaleIdoscopeJit.hを使用します(Datalayoutを公開しなければならなかったことを除く)

"func_works.ll"を使用してプログラムを構築して実行すると、プログラムは次のように成功します。

<事前> <コード> symbol found! address found!

"func_cos_fails.ll"を使ってプログラムを作成して実行すると、プログラムは次のようになります。

<事前> <コード> symbol found! Failure value returned from cantFail wrapped call UNREACHABLE executed at install/llvm-8.0-x86-debug/include/llvm/Support/Error.h:732!

これは、LLVM 8リリースと現在のLLVMトランクで発生します。

誰もが何が起こっているのか見ていますか?

このテストは、

で構成されたLLVMを備えたX86 Linux Ubuntuシステムで実行されました <事前> <コード> cmake -G "Unix Makefiles" -DBUILD_SHARED_LIBS="ON" -DLLVM_ENABLE_RTTI="ON" -DLLVM_ENABLE_ZLIB="OFF" -DLLVM_ENABLE_TERMINFO="OFF" -DCMAKE_BUILD_TYPE="Debug" -DCMAKE_INSTALL_PREFIX=$CMAKE_INSTALL_PREFIX -DLLVM_TARGETS_TO_BUILD="X86" $SRC

test.cc:

<事前> <コード> #include "KaleidoscopeJIT.h" #include "llvm/Analysis/Passes.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/InitLLVM.h" #include <iostream> using namespace llvm; using namespace llvm::orc; int main(int argc, char **argv) { InitLLVM X(argc, argv); EnableDebugBuffering = true; LLVMContext Context; InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); InitializeNativeTargetAsmParser(); cl::ParseCommandLineOptions(argc, argv, "Kaleidoscope example program "); SMDiagnostic Err; std::unique_ptr<llvm::Module> M = parseIRFile( "func_cos_fails.ll" , Err, Context, false); //std::unique_ptr<llvm::Module> M = parseIRFile( "func_works.ll" , Err, Context, false); if (!M) { Err.print("IR parsing failed: ", errs()); return 0; } std::unique_ptr<KaleidoscopeJIT> TheJIT; TheJIT = llvm::make_unique<KaleidoscopeJIT>(); auto H = TheJIT->addModule(std::move(M)); std::string MangledName; llvm::raw_string_ostream MangledNameStream(MangledName); llvm::Mangler::getNameWithPrefix(MangledNameStream, "func_ir" , TheJIT->getDL() ); if (auto Sym = TheJIT->findSymbol(MangledNameStream.str())) { std::cout << "symbol found! "; void* fptr = (void *)cantFail(Sym.getAddress()); std::cout << "address found! "; } else { std::cout << "symbol not found! "; } return 0; }

func_cos_fails.ll:

<事前> <コード> source_filename = "module" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" declare float @cosf(float) define float @func_ir(float %arg0) { entrypoint: %0 = call float @cosf(float %arg0) ret float %0 }

func_works.ll:

<事前> <コード> source_filename = "module" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" define float @func_ir(float %arg0) { entrypoint: ret float %arg0 }

カレイド鏡jit.h:

<事前> <コード> #ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/CompileUtils.h" #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Mangler.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include <algorithm> #include <map> #include <memory> #include <string> #include <vector> namespace llvm { namespace orc { class KaleidoscopeJIT { public: using ObjLayerT = LegacyRTDyldObjectLinkingLayer; using CompileLayerT = LegacyIRCompileLayer<ObjLayerT, SimpleCompiler>; KaleidoscopeJIT() : Resolver(createLegacyLookupResolver( ES, [this](const std::string &Name) { return ObjectLayer.findSymbol(Name, true); }, [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })), TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()), ObjectLayer(ES, [this](VModuleKey) { return ObjLayerT::Resources{ std::make_shared<SectionMemoryManager>(), Resolver}; }), CompileLayer(ObjectLayer, SimpleCompiler(*TM)) { llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr); } TargetMachine &getTargetMachine() { return *TM; } VModuleKey addModule(std::unique_ptr<Module> M) { auto K = ES.allocateVModule(); cantFail(CompileLayer.addModule(K, std::move(M))); ModuleKeys.push_back(K); return K; } void removeModule(VModuleKey K) { ModuleKeys.erase(find(ModuleKeys, K)); cantFail(CompileLayer.removeModule(K)); } JITSymbol findSymbol(const std::string Name) { return findMangledSymbol(mangle(Name)); } const DataLayout& getDL() const { return DL; } private: std::string mangle(const std::string &Name) { std::string MangledName; { raw_string_ostream MangledNameStream(MangledName); Mangler::getNameWithPrefix(MangledNameStream, Name, DL); } return MangledName; } JITSymbol findMangledSymbol(const std::string &Name) { #ifdef _WIN32 // The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported // flag to decide whether a symbol will be visible or not, when we call // IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true. // // But for Windows COFF objects, this flag is currently never set. // For a potential solution see: https://reviews.llvm.org/rL258665 // For now, we allow non-exported symbols on Windows as a workaround. const bool ExportedSymbolsOnly = false; #else const bool ExportedSymbolsOnly = true; #endif // Search modules in reverse order: from last added to first added. // This is the opposite of the usual search order for dlsym, but makes more // sense in a REPL where we want to bind to the newest available definition. for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend())) if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly)) return Sym; // If we can't find the symbol in the JIT, try looking in the host process. if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) return JITSymbol(SymAddr, JITSymbolFlags::Exported); #ifdef _WIN32 // For Windows retry without "_" at beginning, as RTDyldMemoryManager uses // GetProcAddress and standard libraries like msvcrt.dll use names // with and without "_" (for example "_itoa" but "sin"). if (Name.length() > 2 && Name[0] == '_') if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name.substr(1))) return JITSymbol(SymAddr, JITSymbolFlags::Exported); #endif return nullptr; } ExecutionSession ES; std::shared_ptr<SymbolResolver> Resolver; std::unique_ptr<TargetMachine> TM; const DataLayout DL; ObjLayerT ObjectLayer; CompileLayerT CompileLayer; std::vector<VModuleKey> ModuleKeys; }; } // end namespace orc } // end namespace llvm #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H

便宜上、Makefileを提供します:

<事前> <コード> LLVM_CONFIG = ${LLVM_INSTALL_PATH} LLVM_CXXFLAGS = $(shell $(LLVM_CONFIG) --cxxflags) LLVM_LDFLAGS = $(shell $(LLVM_CONFIG) --ldflags) LLVM_LIBS = $(shell $(LLVM_CONFIG) --libs) all: test test.o: test.cc KaleidoscopeJIT.h g++ -c -o $@ $< $(LLVM_CXXFLAGS) test: test.o g++ -o $@ $< $(LLVM_LDFLAGS) $(LLVM_LIBS) clean: rm -f *.o rm -f test
英語

Since LLVM 8 (including current LLVM trunk, aka LLVM 9) I run into a problem when using the ORC JIT ExecutionEngine with functions which contain a call to the standard math library.

The JIT compiler is able to find the symbol for the function but fails to get the address for it in case the function makes a call to the math library.

I attach a simple exploit that shows the problem. The program test.cc reads in an IR file which contains a single function in LLVM's Intermediate Representation: The function takes a single argument, a floating point number, and returns in case of

  • "func_works.ll" the argument itself, and in case of
  • "func_cos_fails.ll" the cosine of the argument.

I didn't implement the choice between the two files at runtime, so the program needs to be rebuilt when switching to the other case.

The program uses the standard KaleidoscopeJIT.h that comes with LLVM (except that I had to expose the Datalayout).

If you build the program with the "func_works.ll" and run it, the program succeeds with:

symbol found! address found! 

If you build the program with the "func_cos_fails.ll" and run it, the program fails with:

symbol found! Failure value returned from cantFail wrapped call UNREACHABLE executed at install/llvm-8.0-x86-debug/include/llvm/Support/Error.h:732! 

This happens with LLVM 8 release and the current LLVM trunk.

Does anyone see what's going on?

This test was run on an x86 Linux Ubuntu system with LLVM configured with

cmake -G "Unix Makefiles"        -DBUILD_SHARED_LIBS="ON"        -DLLVM_ENABLE_RTTI="ON"        -DLLVM_ENABLE_ZLIB="OFF"        -DLLVM_ENABLE_TERMINFO="OFF"        -DCMAKE_BUILD_TYPE="Debug"        -DCMAKE_INSTALL_PREFIX=$CMAKE_INSTALL_PREFIX        -DLLVM_TARGETS_TO_BUILD="X86"        $SRC 

test.cc:

#include "KaleidoscopeJIT.h"  #include "llvm/Analysis/Passes.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/MCJIT.h" #include "llvm/ExecutionEngine/ObjectCache.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/DerivedTypes.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/LegacyPassManager.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" #include "llvm/IRReader/IRReader.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Path.h" #include "llvm/Support/SourceMgr.h" #include "llvm/Support/TargetSelect.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Transforms/Scalar.h" #include "llvm/Support/InitLLVM.h"  #include <iostream>  using namespace llvm; using namespace llvm::orc;     int main(int argc, char **argv) {   InitLLVM X(argc, argv);   EnableDebugBuffering = true;   LLVMContext Context;    InitializeNativeTarget();   InitializeNativeTargetAsmPrinter();   InitializeNativeTargetAsmParser();    cl::ParseCommandLineOptions(argc, argv, "Kaleidoscope example program ");   SMDiagnostic Err;    std::unique_ptr<llvm::Module> M = parseIRFile( "func_cos_fails.ll" , Err, Context, false);   //std::unique_ptr<llvm::Module> M = parseIRFile( "func_works.ll" , Err, Context, false);   if (!M) {     Err.print("IR parsing failed: ", errs());     return 0;   }    std::unique_ptr<KaleidoscopeJIT> TheJIT;    TheJIT = llvm::make_unique<KaleidoscopeJIT>();    auto H = TheJIT->addModule(std::move(M));    std::string MangledName;   llvm::raw_string_ostream MangledNameStream(MangledName);   llvm::Mangler::getNameWithPrefix(MangledNameStream, "func_ir" , TheJIT->getDL() );    if (auto Sym = TheJIT->findSymbol(MangledNameStream.str()))     {       std::cout << "symbol found! ";       void* fptr = (void *)cantFail(Sym.getAddress());        std::cout << "address found! ";     }   else     {       std::cout << "symbol not found! ";     }    return 0; } 

func_cos_fails.ll:

source_filename = "module" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"  declare float @cosf(float)  define float @func_ir(float %arg0) { entrypoint:   %0 = call float @cosf(float %arg0)   ret float %0 } 

func_works.ll:

source_filename = "module" target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"   define float @func_ir(float %arg0) { entrypoint:   ret float %arg0 } 

KaleidoscopeJIT.h:

#ifndef LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H #define LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H  #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/iterator_range.h" #include "llvm/ExecutionEngine/ExecutionEngine.h" #include "llvm/ExecutionEngine/JITSymbol.h" #include "llvm/ExecutionEngine/Orc/CompileUtils.h" #include "llvm/ExecutionEngine/Orc/IRCompileLayer.h" #include "llvm/ExecutionEngine/Orc/LambdaResolver.h" #include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h" #include "llvm/ExecutionEngine/RTDyldMemoryManager.h" #include "llvm/ExecutionEngine/SectionMemoryManager.h" #include "llvm/IR/DataLayout.h" #include "llvm/IR/Mangler.h" #include "llvm/Support/DynamicLibrary.h" #include "llvm/Support/raw_ostream.h" #include "llvm/Target/TargetMachine.h" #include <algorithm> #include <map> #include <memory> #include <string> #include <vector>  namespace llvm { namespace orc {  class KaleidoscopeJIT { public:   using ObjLayerT = LegacyRTDyldObjectLinkingLayer;   using CompileLayerT = LegacyIRCompileLayer<ObjLayerT, SimpleCompiler>;    KaleidoscopeJIT()       : Resolver(createLegacyLookupResolver(             ES,             [this](const std::string &Name) {               return ObjectLayer.findSymbol(Name, true);             },             [](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),         TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),         ObjectLayer(ES,                     [this](VModuleKey) {                       return ObjLayerT::Resources{                           std::make_shared<SectionMemoryManager>(), Resolver};                     }),         CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {     llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);   }    TargetMachine &getTargetMachine() { return *TM; }    VModuleKey addModule(std::unique_ptr<Module> M) {     auto K = ES.allocateVModule();     cantFail(CompileLayer.addModule(K, std::move(M)));     ModuleKeys.push_back(K);     return K;   }    void removeModule(VModuleKey K) {     ModuleKeys.erase(find(ModuleKeys, K));     cantFail(CompileLayer.removeModule(K));   }    JITSymbol findSymbol(const std::string Name) {     return findMangledSymbol(mangle(Name));   }    const DataLayout& getDL() const {     return DL;   }  private:   std::string mangle(const std::string &Name) {     std::string MangledName;     {       raw_string_ostream MangledNameStream(MangledName);       Mangler::getNameWithPrefix(MangledNameStream, Name, DL);     }     return MangledName;   }    JITSymbol findMangledSymbol(const std::string &Name) { #ifdef _WIN32     // The symbol lookup of ObjectLinkingLayer uses the SymbolRef::SF_Exported     // flag to decide whether a symbol will be visible or not, when we call     // IRCompileLayer::findSymbolIn with ExportedSymbolsOnly set to true.     //     // But for Windows COFF objects, this flag is currently never set.     // For a potential solution see: https://reviews.llvm.org/rL258665     // For now, we allow non-exported symbols on Windows as a workaround.     const bool ExportedSymbolsOnly = false; #else     const bool ExportedSymbolsOnly = true; #endif      // Search modules in reverse order: from last added to first added.     // This is the opposite of the usual search order for dlsym, but makes more     // sense in a REPL where we want to bind to the newest available definition.     for (auto H : make_range(ModuleKeys.rbegin(), ModuleKeys.rend()))       if (auto Sym = CompileLayer.findSymbolIn(H, Name, ExportedSymbolsOnly))         return Sym;      // If we can't find the symbol in the JIT, try looking in the host process.     if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))       return JITSymbol(SymAddr, JITSymbolFlags::Exported);  #ifdef _WIN32     // For Windows retry without "_" at beginning, as RTDyldMemoryManager uses     // GetProcAddress and standard libraries like msvcrt.dll use names     // with and without "_" (for example "_itoa" but "sin").     if (Name.length() > 2 && Name[0] == '_')       if (auto SymAddr =               RTDyldMemoryManager::getSymbolAddressInProcess(Name.substr(1)))         return JITSymbol(SymAddr, JITSymbolFlags::Exported); #endif      return nullptr;   }    ExecutionSession ES;   std::shared_ptr<SymbolResolver> Resolver;   std::unique_ptr<TargetMachine> TM;   const DataLayout DL;   ObjLayerT ObjectLayer;   CompileLayerT CompileLayer;   std::vector<VModuleKey> ModuleKeys; };  } // end namespace orc } // end namespace llvm  #endif // LLVM_EXECUTIONENGINE_ORC_KALEIDOSCOPEJIT_H 

for convenience I provide a Makefile:

LLVM_CONFIG = ${LLVM_INSTALL_PATH}  LLVM_CXXFLAGS = $(shell $(LLVM_CONFIG) --cxxflags) LLVM_LDFLAGS  = $(shell $(LLVM_CONFIG) --ldflags) LLVM_LIBS     = $(shell $(LLVM_CONFIG) --libs)  all: test  test.o: test.cc KaleidoscopeJIT.h     g++ -c -o $@ $< $(LLVM_CXXFLAGS)  test: test.o     g++ -o $@ $< $(LLVM_LDFLAGS) $(LLVM_LIBS)  clean:     rm -f *.o     rm -f test 
</div
        
       
       

回答リスト

0
 
vote
私がここに見出された(とにかくLLVM 7および8用)これに対する解決策を信じて: https://stackoverflow.com/a/56862433/2310373 の

つまり、置き換えます:

<事前> <コード> [this](const std::string &Name) { return ObjectLayer.findSymbol(Name, true); },

のようなもので <事前> <コード> [this](const std::string &Name) { auto FoundSymbol = ObjectLayer.findSymbol(Name, true); if (!FoundSymbol) { if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name)) return JITSymbol(SymAddr, JITSymbolFlags::Exported); } return FoundSymbol; },
 

I believe the solution to this (for llvm 7 and 8 anyway) was found here: https://stackoverflow.com/a/56862433/2310373

Namely, replace:

[this](const std::string &Name) {     return ObjectLayer.findSymbol(Name, true); }, 

With something like

[this](const std::string &Name) {     auto FoundSymbol = ObjectLayer.findSymbol(Name, true);     if (!FoundSymbol) {         if (auto SymAddr = RTDyldMemoryManager::getSymbolAddressInProcess(Name))             return JITSymbol(SymAddr, JITSymbolFlags::Exported);     }     return FoundSymbol; }, 
</div
 
 

関連する質問

0  LLVMパスまたはCLANGを使用してint変数をクラスに挿入する  ( Insert int variable into the class using llvm pass or clang ) 
LLVMパスまたはCLANGを使用して、整数変数をすべてのクラスに挿入したい。 これを行う方法? 例えば <事前> <コード> class foo { int a; } 以下のように新しい値を挿入したいです。 <事前> <コード> class ...

1  LLVMビットコードのオペコード番号はどこにありますか?  ( Where can i find the opcode numbers for the llvm bitcode ) 
LLVM IR言語のLLVMバイトコード表現を見つけることができますか? この <result> = add <ty> <op1>, <op2> のように、しかしbinary形式では、この incept JVMの代わりにLLVMの場合。より具体的には、オペコ...

0  clangをBig-Int Xorにしないのはなぜですか?  ( Why doesnt clang vectorise big int xor ) 
この単純な単語単位のXORの例をコンパイルすると、clang 3.4はそれをベクトル化しません。どうして? <a href="http://llvm.org/docs/vectorizers.jp.> http://llvm.org/docs/vectoriz...

0  LLVMとCLANGのワークフロー  ( Workflow of llvm and clang ) 
LLVMの初心者で、(href="https://www.cs.cornell.edu/www.cs.cornell.edu //ww.cs.cornell.edu/~asamson/blog/lvm.html" rel="nofollownoreferre...

4  LLVM IRのすべてのポインタはすべてですか?  ( Is everything a pointer in llvm ir ) 
私はプログラムの世界的なvarsを反復し、彼らの種類に興味を持っています。 テストのための: <事前> <コード> #include <stdio.h> int i=0; int main(){ printf("lala %d ",i); ...

0  LLVM IRのスイッチ命令でCHAR *を使用する方法  ( How to use char in switch instruction of llvm ir ) 
スイッチ命令で文字列を使用しようとしています。 2つのアドレスが等しい場合は、string命令に渡すためにStringの値(constantint *)として文字列のアドレスを使用しています。 switch case が一致する必要があります。 しかし、IRコ...

0  カスタムLLVM IRパスでAFL-CLANG-FASTでバイナリをコンパイルする  ( Compile binary with afl clang fast with custom llvm ir passes ) 
カスタムLLVM IRパスを使用してコンパイル時の計装にAFL FuzzerのClangフロントエンドを使用する方法。 カスタムIRパスを抽出したい場合は、 https://github.com/obfuscator-llvm/obfuscator / AF...

0  LLI命令が解釈されていません  ( Lli instruction not interpretable yet ) 
誰かが私にLLIの指示を説明することができます "%broadcast.splatinsert.i =挿入要素&lt; 4 x i32&gt; undef、i32%reverse.idx.i、i32 0" 印刷されていません。? LLI Ver 3.3 フ...

1  LLVM-IRのPHI命令セマンティクス  ( Phi instruction semantics in llvm ir ) 
LLVM-IR のPHI命令セマンティクスを理解しようとしています。 ( https://llvm.org/docs/langref.html#phi-命令) 次の例を考えてみましょう。 <事前> <コード> ; Function Attrs: norec...

2  LLVM ::命令がフロー制御内にある場合に見つける方法  ( How to find if an llvminstruction lies within flow control ) 
LLVMでは、命令がフロー制御(if / switch / switch / for)などに存在するかどうかを調べようとしていて、IRレベルでこれを行う必要があります。疑似コードは以下のようなものです。 <事前> <コード> Untitled.cpp:29:...




© 2022 cndgn.com All Rights Reserved. Q&Aハウス 全著作権所有