├── fuzzing ├── .gitignore ├── reduce.sh ├── fuzz-docker.sh ├── shell.nix ├── README.md ├── Dockerfile └── fuzz.sh ├── disasm-test ├── llvm-tests │ ├── .gitignore │ ├── mdnodes-distinct-nodes-first.ll │ ├── README.md │ ├── LICENSE │ ├── cfi-eof-prologue.new.ll │ └── cfi-eof-prologue.old.ll ├── .gitignore ├── cpp │ ├── .gitignore │ ├── return0.cpp │ ├── templates.h │ ├── atomicrmw.cpp │ ├── iostream.cpp │ ├── templates.cpp │ ├── libcxxbc.nix │ ├── README.md │ ├── atomicrmw.nix │ ├── generate.sh │ ├── return0.ll │ └── templates.ll ├── tests │ ├── poison.pre-llvm12.ll │ ├── di-arg-list.pre-llvm13.ll │ ├── dilocalvariable.pre-llvm14.ll │ ├── btf-tag-diderivedtype.pre-llvm14.ll │ ├── btf-tag-disubprogram.pre-llvm14.ll │ ├── btf-tag-dicompositetype.pre-llvm14.ll │ ├── btf-tag-diglobalvariable.pre-llvm14.ll │ ├── btf-tag-dilocalvariable.pre-llvm14.ll │ ├── fun-attrs.ll │ ├── poison.ll │ ├── hello-world.ll │ ├── global-array.ll │ ├── di-arg-list.c │ ├── T266-constant-icmp.ll │ ├── simple-res.ll │ ├── simple-metadata.ll │ ├── half-float.ll │ ├── T258.c │ ├── derivedtype.c │ ├── uitofp-nneg.pre-llvm19.ll │ ├── zext-nneg.ll │ ├── zext-nneg.pre-llvm18.ll │ ├── icmp-samesign.pre-llvm20.ll │ ├── trunc-nuw-nsw.pre-llvm20.ll │ ├── uitofp-nneg.ll │ ├── T258.pre-llvm17.ll │ ├── icmp-samesign.ll │ ├── opaque-call.pre-llvm15.ll │ ├── opaque-atomicrmw.pre-llvm15.ll │ ├── opaque-getelementptr.pre-llvm15.ll │ ├── atomicrmw-faddsub.pre-llvm9.ll │ ├── opaque-constant-getelementptr.pre-llvm15.ll │ ├── atomicrmw-fmaxmin.pre-llvm15.ll │ ├── global-var.c │ ├── atomicrmw-uincdecwrap.pre-llvm16.ll │ ├── inrange_arg.pre-llvm19.ll │ ├── mutual-struct-rec.ll │ ├── opaque-atomicrmw-uincdecwrap.pre-llvm16.ll │ ├── atomicrmw-faddsub.ll │ ├── atomicrmw-fmaxmin.ll │ ├── atomicrmw-uincdecwrap.ll │ ├── global-var-extern.c │ ├── opaque-atomicrmw-uincdecwrap.ll │ ├── T266-constant-icmp.pre-llvm19.ll │ ├── T266-constant-icmp.pre-llvm15.ll │ ├── switch-same-target.ll │ ├── opaque-call.ll │ ├── anon-forward-ref.ll │ ├── cmpxchg.c │ ├── switch.ll │ ├── trunc-nuw-nsw.ll │ ├── fn-metadata.ll │ ├── switch-simple.ll │ ├── switch-big-value.ll │ ├── opaque-getelementptr.ll │ ├── struct-initializer.ll │ ├── T189.c │ ├── insertelt.ll │ ├── inrange_arg.post-llvm18.ll │ ├── opaque-constant-getelementptr.ll │ ├── diderivedtype-address-space.at-least-llvm14.ll │ ├── fneg.ll │ ├── global-var.ll │ ├── localstatic.c │ ├── factorial2.ll │ ├── phi-anon.ll │ ├── callbr.c │ ├── btf-tag-dicompositetype.ll │ ├── atomicrmw.ll │ ├── btf-tag-diderivedtype.ll │ ├── smallprog.c │ ├── opaque-atomicrmw.ll │ ├── btf-tag-dilocalvariable.ll │ ├── btf-tag-diglobalvariable.ll │ ├── btf-tag-disubprogram.ll │ ├── fcmp-fast-math.ll │ ├── instrmd.ll │ ├── global-var-extern.ll │ ├── dilocalvariable.ll │ ├── callbr.pre-llvm15.ll │ ├── callbr.ll │ ├── T189.ll │ ├── p0.c │ ├── di-arg-list.ll │ ├── derivedtype.ll │ ├── T258.ll │ └── cmpxchg.ll ├── failing │ ├── global.ll │ └── metadata.ll ├── bc_src_tests │ ├── hello-world.ll │ ├── apple-llvm.bc │ ├── hello-world.bc │ ├── fn-data-layout.bc │ ├── fn-data-layout.ll │ └── README.md ├── known_bugs │ ├── pr247 │ └── README.md ├── README.md └── Instances.hs ├── examples ├── .gitignore ├── test.c ├── Makefile └── Factorial.hs ├── Setup.hs ├── cabal.project ├── .gitmodules ├── .gitignore ├── src └── Data │ └── LLVM │ ├── Internal.hs │ ├── BitCode │ ├── IR │ │ ├── Attrs.hs │ │ ├── Globals.hs │ │ ├── Blocks.hs │ │ ├── Values.hs │ │ └── Types.hs │ ├── IR.hs │ ├── Match.hs │ ├── Assert.hs │ ├── BitString.hs │ └── Record.hs │ └── BitCode.hs ├── unit-test ├── Main.hs └── Tests │ ├── PrimInstances.hs │ ├── StmtInstances.hs │ ├── TripleInstances.hs │ ├── FuncDataInstances.hs │ ├── Metadata.hs │ ├── Instances.hs │ └── ExpressionInstances.hs ├── regression-test └── README.md ├── LICENSE ├── .github └── workflows │ ├── build.yml │ ├── nix-ci.yml │ └── llvm-quick-fuzz.yml ├── CHANGELOG.md ├── llvm-disasm └── LLVMDis.hs ├── doc └── developing.md └── README.md /fuzzing/.gitignore: -------------------------------------------------------------------------------- 1 | fuzz-results/ -------------------------------------------------------------------------------- /disasm-test/llvm-tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.bc -------------------------------------------------------------------------------- /disasm-test/.gitignore: -------------------------------------------------------------------------------- 1 | ghc 2 | runtest 3 | -------------------------------------------------------------------------------- /disasm-test/cpp/.gitignore: -------------------------------------------------------------------------------- 1 | *.bc 2 | *.xml -------------------------------------------------------------------------------- /examples/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.ll 3 | *.bc 4 | -------------------------------------------------------------------------------- /disasm-test/tests/poison.pre-llvm12.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/failing/global.ll: -------------------------------------------------------------------------------- 1 | @value = global i32 10 2 | -------------------------------------------------------------------------------- /disasm-test/tests/di-arg-list.pre-llvm13.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /disasm-test/tests/dilocalvariable.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-diderivedtype.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-disubprogram.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-dicompositetype.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-diglobalvariable.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-dilocalvariable.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/fun-attrs.ll: -------------------------------------------------------------------------------- 1 | 2 | define private i32 @x() { 3 | ret i32 10 4 | } 5 | -------------------------------------------------------------------------------- /disasm-test/tests/poison.ll: -------------------------------------------------------------------------------- 1 | define double @f(i32 %x) { 2 | ret double poison 3 | } 4 | -------------------------------------------------------------------------------- /disasm-test/tests/hello-world.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @hello_world() { 3 | ret void 4 | } 5 | -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/hello-world.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @hello_world() { 3 | ret void 4 | } 5 | -------------------------------------------------------------------------------- /disasm-test/tests/global-array.ll: -------------------------------------------------------------------------------- 1 | 2 | @val = internal constant [1 x i16] [i16 1], align 8 3 | -------------------------------------------------------------------------------- /cabal.project: -------------------------------------------------------------------------------- 1 | packages: . 2 | optional-packages: llvm-pretty 3 | constraints: directory >= 1.2.7 4 | -------------------------------------------------------------------------------- /disasm-test/tests/di-arg-list.c: -------------------------------------------------------------------------------- 1 | int f(int x, int y) { 2 | int z = x + y; 3 | return 0; 4 | } 5 | -------------------------------------------------------------------------------- /disasm-test/tests/T266-constant-icmp.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST icmp constexprs are no longer supported as of llvm-19 2 | -------------------------------------------------------------------------------- /disasm-test/tests/simple-res.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @f(i32 %a) { 3 | %b = add i32 %a, 5 4 | ret i32 %b 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/simple-metadata.ll: -------------------------------------------------------------------------------- 1 | 2 | !0 = !{ !"string" } 3 | 4 | define void @f() { 5 | ret void 6 | } 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "llvm-pretty"] 2 | path = llvm-pretty 3 | url = https://github.com/GaloisInc/llvm-pretty.git 4 | -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/apple-llvm.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaloisInc/llvm-pretty-bc-parser/HEAD/disasm-test/bc_src_tests/apple-llvm.bc -------------------------------------------------------------------------------- /disasm-test/tests/half-float.ll: -------------------------------------------------------------------------------- 1 | 2 | define half @f(double %x) { 3 | %y = fptrunc double %x to half 4 | ret half %y 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/hello-world.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaloisInc/llvm-pretty-bc-parser/HEAD/disasm-test/bc_src_tests/hello-world.bc -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/fn-data-layout.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaloisInc/llvm-pretty-bc-parser/HEAD/disasm-test/bc_src_tests/fn-data-layout.bc -------------------------------------------------------------------------------- /disasm-test/tests/T258.c: -------------------------------------------------------------------------------- 1 | __attribute__((__noinline__)) void f(int* x) {} 2 | 3 | int main(void) { 4 | int x; 5 | f(&x); 6 | return 0; 7 | } 8 | -------------------------------------------------------------------------------- /disasm-test/tests/derivedtype.c: -------------------------------------------------------------------------------- 1 | struct message { int msglen; char* msgptr; }; 2 | 3 | int foo(struct message* mptr) { 4 | return mptr->msglen; 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/uitofp-nneg.pre-llvm19.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case uses an nneg flag with a uitofp instruction, which requires LLVM 4 | 19 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/zext-nneg.ll: -------------------------------------------------------------------------------- 1 | define void @test_zext(i32 %a) { 2 | %res1 = zext nneg i32 %a to i64 3 | %res2 = zext i32 %a to i64 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/zext-nneg.pre-llvm18.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case uses an nneg flag with an zext instruction, which requires LLVM 4 | 18 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/icmp-samesign.pre-llvm20.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case uses a samesign flag with an icmp instruction, which requires 4 | LLVM 20 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/trunc-nuw-nsw.pre-llvm20.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case uses nuw/nsw flags with a trunc instruction, which requires LLVM 4 | 20 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/uitofp-nneg.ll: -------------------------------------------------------------------------------- 1 | define void @test_uitofp(i32 %a) { 2 | %res1 = uitofp nneg i32 %a to float 3 | %res2 = uitofp i32 %a to float 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/cpp/return0.cpp: -------------------------------------------------------------------------------- 1 | // The corresponding ll file was generated with Clang++ 6 with: 2 | // clang++ -O0 -g -emit-llvm -c 3 | int main() 4 | { 5 | return 0; 6 | } 7 | -------------------------------------------------------------------------------- /disasm-test/tests/T258.pre-llvm17.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of the DIAssignID metadata node, which is only 4 | available with LLVM 17 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/icmp-samesign.ll: -------------------------------------------------------------------------------- 1 | define void @test_icmp(i32 %a, i32 %b) { 2 | %res1 = icmp samesign ult i32 %a, %b 3 | %res2 = icmp ult i32 %a, %b 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-call.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of opaque pointers, which are most easily 4 | usable with LLVM 15 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-atomicrmw.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of opaque pointers, which are most easily 4 | usable with LLVM 15 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-getelementptr.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of opaque pointers, which are most easily 4 | usable with LLVM 15 or later. 5 | -------------------------------------------------------------------------------- /examples/test.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | extern int factorial(int); 4 | 5 | int main() { 6 | printf("factorial(%d) = %d\n", 5, factorial(5)); 7 | 8 | return 0; 9 | } 10 | -------------------------------------------------------------------------------- /disasm-test/tests/atomicrmw-faddsub.pre-llvm9.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of atomic `fadd` and `fsub` operations, which 4 | are only available in LLVM 9 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-constant-getelementptr.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of opaque pointers, which are most easily 4 | usable with LLVM 15 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/atomicrmw-fmaxmin.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of atomic `fmax` and `fmin` operations, which 4 | are only available in LLVM 15 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/cpp/templates.h: -------------------------------------------------------------------------------- 1 | #ifdef __cplusplus 2 | extern "C" { 3 | #endif 4 | 5 | int nonzeroChar(char a); 6 | int nonzeroInt(int a); 7 | 8 | #ifdef __cplusplus 9 | } 10 | #endif 11 | -------------------------------------------------------------------------------- /disasm-test/tests/global-var.c: -------------------------------------------------------------------------------- 1 | int global_var; 2 | 3 | int global_var2 = 2; 4 | 5 | struct s { char fld1; int fld2; } s_global; 6 | 7 | struct s2 { int fld1; char fld2; } s2_global = { 3, 'a' }; 8 | -------------------------------------------------------------------------------- /disasm-test/tests/atomicrmw-uincdecwrap.pre-llvm16.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of atomic `uinc_wrap` and `udec_wrap` 4 | operations, which are only available in LLVM 16 or later. 5 | -------------------------------------------------------------------------------- /disasm-test/tests/inrange_arg.pre-llvm19.ll: -------------------------------------------------------------------------------- 1 | define i8** @constexpr() { 2 | ret i8** getelementptr inbounds ({ [4 x i8*], [4 x i8*] }, { [4 x i8*], [4 x i8*] }* null, i32 0, inrange i32 1, i32 2) 3 | } 4 | -------------------------------------------------------------------------------- /disasm-test/tests/mutual-struct-rec.ll: -------------------------------------------------------------------------------- 1 | 2 | %struct.A = type { i32, %struct.B* } 3 | %struct.B = type { i32, %struct.A* } 4 | 5 | define %struct.A* @f(%struct.A* %ptr) { 6 | ret %struct.A* %ptr 7 | } 8 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-atomicrmw-uincdecwrap.pre-llvm16.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | 3 | This test case requires the use of atomic `uinc_wrap` and `udec_wrap` 4 | operations, which are only available in LLVM 16 or later. 5 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .cabal-sandbox/ 3 | cabal.sandbox.config 4 | .stack-work/ 5 | .ghc.environment.* 6 | /dist-newstyle 7 | /fuzz-temp-test.c 8 | /fuzz-temp-test.bc 9 | /fuzz-results 10 | .boring 11 | _darcs/ 12 | -------------------------------------------------------------------------------- /disasm-test/cpp/atomicrmw.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | struct HP { 4 | std::string x; 5 | std::string y; 6 | }; 7 | 8 | int test_me() { 9 | HP hp; 10 | hp.x = ""; 11 | return hp.y.length(); 12 | } 13 | -------------------------------------------------------------------------------- /disasm-test/cpp/iostream.cpp: -------------------------------------------------------------------------------- 1 | // This file generates _a lot_ of debug info because of the inclusion of iostream. 2 | #include 3 | 4 | int main() 5 | { 6 | std::cout << "Hello world!"; 7 | return 0; 8 | } 9 | -------------------------------------------------------------------------------- /disasm-test/tests/atomicrmw-faddsub.ll: -------------------------------------------------------------------------------- 1 | define void @atomicrmw(float* %a, float %f) { 2 | %b11 = atomicrmw fadd float* %a, float %f acquire 3 | %b12 = atomicrmw fsub float* %a, float %f acquire 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/atomicrmw-fmaxmin.ll: -------------------------------------------------------------------------------- 1 | define void @atomicrmw(float* %a, float %f) { 2 | %b13 = atomicrmw fmax float* %a, float %f acquire 3 | %b14 = atomicrmw fmin float* %a, float %f acquire 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/atomicrmw-uincdecwrap.ll: -------------------------------------------------------------------------------- 1 | define void @atomicrmw(i32* %a, i32 %i) { 2 | %b15 = atomicrmw uinc_wrap i32* %a, i32 %i acquire 3 | %b16 = atomicrmw udec_wrap i32* %a, i32 %i acquire 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /disasm-test/tests/global-var-extern.c: -------------------------------------------------------------------------------- 1 | extern int global_var; 2 | 3 | extern struct s { int fld1; char fld2; } global_struct; 4 | 5 | int foo(void) { return global_var; } 6 | 7 | struct s* bar(void) { return &global_struct; } 8 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-atomicrmw-uincdecwrap.ll: -------------------------------------------------------------------------------- 1 | define void @atomicrmw(ptr %a, i32 %i) { 2 | %b15 = atomicrmw uinc_wrap ptr %a, i32 %i acquire 3 | %b16 = atomicrmw udec_wrap ptr %a, i32 %i acquire 4 | ret void 5 | } 6 | -------------------------------------------------------------------------------- /src/Data/LLVM/Internal.hs: -------------------------------------------------------------------------------- 1 | -- | This module exports some internal modules *for use in testing only*. 2 | module Data.LLVM.Internal 3 | ( module Data.LLVM.BitCode.IR.Metadata 4 | ) where 5 | 6 | import Data.LLVM.BitCode.IR.Metadata 7 | -------------------------------------------------------------------------------- /disasm-test/tests/T266-constant-icmp.pre-llvm19.ll: -------------------------------------------------------------------------------- 1 | @global_var = external constant [1 x i8] 2 | 3 | define i64 @h() { 4 | br i1 icmp ne (i32 ptrtoint (ptr @global_var to i32), i32 1), label %pc_1, label %pc_1 5 | pc_1: 6 | ret i64 0 7 | } 8 | -------------------------------------------------------------------------------- /disasm-test/tests/T266-constant-icmp.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | @global_var = external constant [1 x i8] 2 | 3 | define i64 @h() { 4 | br i1 icmp ne (i32 ptrtoint ([1 x i8]* @global_var to i32), i32 1), label %pc_1, label %pc_1 5 | pc_1: 6 | ret i64 0 7 | } 8 | -------------------------------------------------------------------------------- /disasm-test/tests/switch-same-target.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @f(i32 %x) { 3 | switch i32 %x, label %default [ 4 | i32 1, label %isOne 5 | i32 2, label %isOne 6 | ] 7 | 8 | default: 9 | ret i32 0 10 | 11 | isOne: 12 | ret i32 1 13 | } 14 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-call.ll: -------------------------------------------------------------------------------- 1 | define void @f(i32 %x) { 2 | ret void 3 | } 4 | 5 | define void @g() { 6 | %p = alloca ptr 7 | store ptr @f, ptr %p 8 | %f = load ptr, ptr %p 9 | call void (i32) %f(i32 42) 10 | ret void 11 | } 12 | -------------------------------------------------------------------------------- /unit-test/Main.hs: -------------------------------------------------------------------------------- 1 | module Main (main) where 2 | 3 | import qualified Test.Tasty as T 4 | import qualified Tests.Metadata 5 | 6 | main :: IO () 7 | main = T.defaultMain $ T.testGroup "Tests" [ Tests.Metadata.tests 8 | ] 9 | -------------------------------------------------------------------------------- /disasm-test/tests/anon-forward-ref.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @f() { 3 | 4 | br label %bar 5 | 6 | foo: 7 | %1 = add i32 %2, 10 8 | br label %exit 9 | 10 | bar: 11 | %2 = add i32 0, 10 12 | br label %foo 13 | 14 | exit: 15 | ret void 16 | 17 | } 18 | -------------------------------------------------------------------------------- /disasm-test/tests/cmpxchg.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | atomic_int val = 0x928; 5 | 6 | int do_atomic_update(atomic_int newval) { 7 | int old_val = 0x928; 8 | return atomic_compare_exchange_weak(&val, &old_val, newval); 9 | } 10 | -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/fn-data-layout.ll: -------------------------------------------------------------------------------- 1 | ; A regression test for #292. This ensures that we can parse data layout strings 2 | ; that specify function pointer alignment (i.e., the Fn32 part in the string 3 | ; below). 4 | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128-Fn32" 5 | -------------------------------------------------------------------------------- /disasm-test/tests/switch.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @f(i32 %x) { 3 | switch i32 %x, label %default [ 4 | i32 1, label %isOne 5 | i32 2, label %isTwo 6 | ] 7 | 8 | default: 9 | ret i32 0 10 | 11 | isOne: 12 | ret i32 1 13 | 14 | isTwo: 15 | ret i32 10 16 | } 17 | -------------------------------------------------------------------------------- /disasm-test/tests/trunc-nuw-nsw.ll: -------------------------------------------------------------------------------- 1 | define void @test_trunc(i64 %a) { 2 | %res1 = trunc nuw i64 %a to i32 3 | %res2 = trunc nsw i64 %a to i32 4 | %res3 = trunc nuw nsw i64 %a to i32 5 | %res4 = trunc nsw nuw i64 %a to i32 6 | %res5 = trunc i64 %a to i32 7 | ret void 8 | } 9 | -------------------------------------------------------------------------------- /disasm-test/cpp/templates.cpp: -------------------------------------------------------------------------------- 1 | #include "templates.h" 2 | 3 | template 4 | int nonzero(T a) { 5 | return a != 0; 6 | } 7 | 8 | extern "C" { 9 | int nonzeroChar(char a) { return nonzero(a); } 10 | int nonzeroInt(int a) { return nonzero(a); } 11 | } 12 | -------------------------------------------------------------------------------- /disasm-test/failing/metadata.ll: -------------------------------------------------------------------------------- 1 | 2 | ; Some unnamed metadata nodes, which are referenced by the named metadata. 3 | !0 = !{ !"zero" } 4 | !1 = !{ !{ !"three" }, !2 } 5 | !2 = !{ !"one" } 6 | 7 | ; A named metadata. 8 | !thinger = !{ !0, !1, !2 } 9 | 10 | @val = global i32 10 11 | -------------------------------------------------------------------------------- /disasm-test/tests/fn-metadata.ll: -------------------------------------------------------------------------------- 1 | 2 | declare void @llvm.dbg.declare(metadata, metadata, metadata) 3 | 4 | define void @f(i32 %x) { 5 | %y = add i32 %x, 20 6 | call void @llvm.dbg.declare( metadata i32 %x, metadata !{ !"x" }, metadata !{ 7 | !"0x102" }) 8 | ret void 9 | } 10 | -------------------------------------------------------------------------------- /disasm-test/tests/switch-simple.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @f(i32 %x) { 3 | switch i32 %x, label %default [ 4 | i32 1, label %isOne 5 | i32 2, label %isTwo 6 | ] 7 | 8 | default: 9 | ret i32 0 10 | 11 | isOne: 12 | ret i32 1 13 | 14 | isTwo: 15 | ret i32 10 16 | } 17 | -------------------------------------------------------------------------------- /disasm-test/tests/switch-big-value.ll: -------------------------------------------------------------------------------- 1 | 2 | define i32 @f(i512 %x) { 3 | switch i512 %x, label %default [ 4 | i512 9223372036854775808, label %isOne 5 | i512 19223372036854775808, label %isOne 6 | ] 7 | 8 | default: 9 | ret i32 0 10 | 11 | isOne: 12 | ret i32 1 13 | } 14 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-getelementptr.ll: -------------------------------------------------------------------------------- 1 | %struct.RT = type { i8, [10 x [20 x i32]], i8 } 2 | %struct.ST = type { i32, double, %struct.RT } 3 | 4 | define ptr @foo(ptr %s) { 5 | entry: 6 | %arrayidx = getelementptr inbounds %struct.ST, ptr %s, i64 1, i32 2, i32 1, i64 5, i64 13 7 | ret ptr %arrayidx 8 | } 9 | -------------------------------------------------------------------------------- /disasm-test/tests/struct-initializer.ll: -------------------------------------------------------------------------------- 1 | 2 | %0 = type { i32, i8, [3 x i8] } 3 | %1 = type { i32, [6 x i8], [2 x i8] } 4 | 5 | @struct_test.b = internal constant %0 { i32 99, i8 122, [3 x i8] undef }, align 4 6 | @struct_test_two.x = internal constant %1 { i32 1, [6 x i8] c"fredd\00", [2 x i8] undef }, align 4 7 | -------------------------------------------------------------------------------- /disasm-test/tests/T189.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | void f() { 4 | // This code has been carefully designed so that the resulting .ll file 5 | // will contain an explicit function type in a `call` instruction. 6 | // See #189 for more information. 7 | int (*p)(const char*, ...) = &printf; 8 | p("%d\n", 0); 9 | } 10 | -------------------------------------------------------------------------------- /disasm-test/known_bugs/pr247: -------------------------------------------------------------------------------- 1 | ##> rootMatchName: apple-llvm.bc 2 | ##> summary: unnamed metadata indices are currently duplicated 3 | 4 | This is a manifestation of 5 | https://github.com/GaloisInc/llvm-pretty-bc-parser/issues/222, which will 6 | eventually be address by 7 | https://github.com/GaloisInc/llvm-pretty-bc-parser/pull/228. 8 | -------------------------------------------------------------------------------- /disasm-test/tests/insertelt.ll: -------------------------------------------------------------------------------- 1 | 2 | define <4 x i8> @f(i8 %a, i8 %b, i8 %c, i8 %d) { 3 | %1 = insertelement <4 x i8> undef, i8 %a, i32 0 4 | %2 = insertelement <4 x i8> %1, i8 %b, i32 1 5 | %3 = insertelement <4 x i8> %2, i8 %c, i32 2 6 | %4 = insertelement <4 x i8> %3, i8 %d, i32 3 7 | 8 | ret <4 x i8> %3 9 | } 10 | -------------------------------------------------------------------------------- /disasm-test/tests/inrange_arg.post-llvm18.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'kwq_18.bc' 2 | source_filename = "disasm-test/tests/inrange_arg.pre-llvm19.ll" 3 | 4 | define ptr @constexpr() { 5 | ret ptr getelementptr inbounds ({ [4 x ptr], [4 x ptr] }, ptr null, i32 0, i32 1, i32 2) 6 | ret ptr getelementptr inbounds nuw inrange(-8, 8) (i8, ptr null, i64 16) 7 | } 8 | -------------------------------------------------------------------------------- /disasm-test/tests/opaque-constant-getelementptr.ll: -------------------------------------------------------------------------------- 1 | %struct.RT = type { i8, [10 x [20 x i32]], i8 } 2 | %struct.ST = type { i32, double, %struct.RT } 3 | 4 | @.s = private constant %struct.ST zeroinitializer 5 | 6 | define ptr @foo() { 7 | entry: 8 | ret ptr getelementptr inbounds (%struct.ST, ptr @.s, i64 1, i32 2, i32 1, i64 5, i64 13) 9 | } 10 | -------------------------------------------------------------------------------- /disasm-test/cpp/libcxxbc.nix: -------------------------------------------------------------------------------- 1 | with import { }; 2 | 3 | llvmPackages_6.libcxx.overrideAttrs (oldAttrs: { 4 | stdenv = llvmPackages_6.stdenv; 5 | buildInputs = [clang] ++ oldAttrs.buildInputs; 6 | cmakeFlags = "-DCMAKE_CXX_FLAGS=-save-temps -DCMAKE_CXX_COMPILER=clang++"; 7 | 8 | installPhase = '' 9 | mkdir -p $out 10 | cp lib/*.bc $out 11 | ''; 12 | }) 13 | -------------------------------------------------------------------------------- /disasm-test/tests/diderivedtype-address-space.at-least-llvm14.ll: -------------------------------------------------------------------------------- 1 | ;; Adapted from https://github.com/llvm/llvm-project/blob/d5561e0a0bbd484da17d3b68ae5fedc0a057246b/llvm/test/Assembler/debug-info.ll 2 | 3 | !7 = !DIBasicType(tag: DW_TAG_base_type, name: "name", size: 1, align: 2, encoding: DW_ATE_unsigned_char) 4 | !15 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !7, size: 32, align: 32, dwarfAddressSpace: 1) 5 | -------------------------------------------------------------------------------- /examples/Makefile: -------------------------------------------------------------------------------- 1 | 2 | GHC = ghc 3 | 4 | all: 5 | 6 | %.bc: %.ll 7 | llvm-as -o $@ $< 8 | 9 | %.s: %.bc 10 | llc -o $@ $< 11 | 12 | all: factorial 13 | factorial: factorial.o test.o 14 | $(CC) -o $@ $^ 15 | 16 | factorial.ll: Factorial.hs 17 | $(GHC) -i../src Factorial.hs -e factorialDoc > $@ 18 | 19 | clean: clean-factorial 20 | clean-factorial: 21 | $(RM) factorial factorial.ll factorial.o test.o 22 | 23 | -------------------------------------------------------------------------------- /disasm-test/tests/fneg.ll: -------------------------------------------------------------------------------- 1 | define double @real_fneg(double %X) { 2 | %Y = fneg double %X ; [#uses=1] 3 | ret double %Y 4 | } 5 | 6 | define double @real_fneg_constant() { 7 | %Y = fneg double -2.0 ; [#uses=1] 8 | ret double %Y 9 | } 10 | 11 | define float @real_fnegf(float %X) { 12 | %Y = fneg float %X ; [#uses=1] 13 | ret float %Y 14 | } 15 | -------------------------------------------------------------------------------- /disasm-test/cpp/README.md: -------------------------------------------------------------------------------- 1 | # C++ tests 2 | 3 | The assembly files were generated using the `generate.sh` script, which details 4 | which versions of `clang++` and `llvm-as** they are expected to work with. 5 | 6 | **Note**: This is true except for `atomicrmw.ll` which is generated from `nix-build atomicrmw.nix`. 7 | 8 | Passes roundtrip: 9 | - `return0.ll` 10 | 11 | Parses, but fails roundtrip: 12 | - `atomicrmw.ll` 13 | - `iostream.ll` 14 | - `templates.ll` 15 | - `merge.ll` 16 | -------------------------------------------------------------------------------- /disasm-test/tests/global-var.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'global-var.bc' 2 | source_filename = "disasm-test/tests/global-var.c" 3 | target datalayout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-f80:128-n8:16:32:64-S128" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | @global_var = global i32 0, align 4 7 | 8 | !llvm.module.flags = !{!0, !1} 9 | !llvm.ident = !{!2} 10 | 11 | !0 = !{i32 1, !"wchar_size", i32 4} 12 | !1 = !{i32 7, !"PIC Level", i32 2} 13 | !2 = !{!"clang version 11.1.0"} 14 | -------------------------------------------------------------------------------- /disasm-test/tests/localstatic.c: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #define NUM 3 4 | 5 | int has_local_static(int x) { 6 | int y; 7 | static const void *const disptab[NUM] = { &&fn1, &&fn2, &&fn3 }; 8 | y = x; 9 | start: 10 | goto *disptab[y]; 11 | fn1: 12 | y += 1; 13 | goto *disptab[y]; 14 | fn2: 15 | y *= 3; 16 | goto start; 17 | fn3: 18 | return y; 19 | } 20 | 21 | int main(int argc, char** argv) { 22 | printf("= %d\n", has_local_static(argc)); 23 | } 24 | -------------------------------------------------------------------------------- /fuzzing/reduce.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Consider this script a template for reducing failing test cases. In 4 | # particular, not each bug will manifest in the same way, giving the 5 | # same error message, so modify the grep condition appropriately for 6 | # each bug. 7 | 8 | clang -I${CSMITH_PATH} -O -g -w -c -emit-llvm fuzz-temp-test.c -o fuzz-temp-test.bc; 9 | if [ $? -ne 0 ]; then 10 | exit 1 11 | fi 12 | llvm-disasm fuzz-temp-test.bc 2>&1 | grep 'is missing from the symbol table' 13 | -------------------------------------------------------------------------------- /disasm-test/cpp/atomicrmw.nix: -------------------------------------------------------------------------------- 1 | with import { }; 2 | 3 | let libcxxbc = import ./libcxxbc.nix; 4 | in llvmPackages_6.stdenv.mkDerivation { 5 | name = "atomicrmw"; 6 | buildInputs = [ clang llvm_6 ]; 7 | src = lib.sourceFilesBySuffices ./. [ ".cpp" ]; 8 | buildPhase = '' 9 | clang++ -emit-llvm -g -O0 -o atomicrmw.bc -c atomicrmw.cpp 10 | llvm-link -only-needed ${libcxxbc}/*.bc atomicrmw.bc > atomicrmw.bc 11 | ''; 12 | installPhase = '' 13 | mkdir -p $out 14 | cp *.bc $out/ 15 | ''; 16 | 17 | } 18 | -------------------------------------------------------------------------------- /disasm-test/tests/factorial2.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'test.bc' 2 | 3 | define i32 @factorial(i32 %a0) { 4 | br label %test 5 | 6 | test: ; preds = %incr, %0 7 | %1 = phi i32 [ %a0, %0 ], [ %6, %4 ] 8 | %2 = phi i32 [ 1, %0 ], [ %5, %4 ] 9 | %3 = icmp ule i32 %2, 1 10 | br i1 %3, label %exit, label %4 11 | 12 | ;