├── .github └── workflows │ ├── build.yml │ ├── llvm-quick-fuzz.yml │ └── nix-ci.yml ├── .gitignore ├── .gitmodules ├── CHANGELOG.md ├── LICENSE ├── README.md ├── Setup.hs ├── cabal.project ├── disasm-test ├── .gitignore ├── Main.hs ├── README.md ├── bc_src_tests │ ├── README.md │ ├── apple-llvm.bc │ ├── apple-llvm.ll │ ├── hello-world.bc │ └── hello-world.ll ├── cpp │ ├── .gitignore │ ├── README.md │ ├── atomicrmw.cpp │ ├── atomicrmw.ll │ ├── atomicrmw.nix │ ├── generate.sh │ ├── iostream.cpp │ ├── iostream.ll │ ├── libcxxbc.nix │ ├── merge.ll │ ├── return0.cpp │ ├── return0.ll │ ├── templates.cpp │ ├── templates.h │ └── templates.ll ├── failing │ ├── global.ll │ └── metadata.ll ├── known_bugs │ ├── README.md │ ├── llvm_dbg_declare_inline │ └── pr247 ├── llvm-tests │ ├── .gitignore │ ├── LICENSE │ ├── README.md │ ├── cfi-eof-prologue.new.ll │ ├── cfi-eof-prologue.old.ll │ └── mdnodes-distinct-nodes-first.ll └── tests │ ├── T189.c │ ├── T189.ll │ ├── T266-constant-icmp.ll │ ├── T266-constant-icmp.pre-llvm15.ll │ ├── anon-forward-ref.ll │ ├── atomicrmw-faddsub.ll │ ├── atomicrmw-faddsub.pre-llvm9.ll │ ├── atomicrmw-fmaxmin.ll │ ├── atomicrmw-fmaxmin.pre-llvm15.ll │ ├── atomicrmw-uincdecwrap.ll │ ├── atomicrmw-uincdecwrap.pre-llvm16.ll │ ├── atomicrmw.ll │ ├── btf-tag-dicompositetype.ll │ ├── btf-tag-dicompositetype.pre-llvm14.ll │ ├── btf-tag-diderivedtype.ll │ ├── btf-tag-diderivedtype.pre-llvm14.ll │ ├── btf-tag-diglobalvariable.ll │ ├── btf-tag-diglobalvariable.pre-llvm14.ll │ ├── btf-tag-dilocalvariable.ll │ ├── btf-tag-dilocalvariable.pre-llvm14.ll │ ├── btf-tag-disubprogram.ll │ ├── btf-tag-disubprogram.pre-llvm14.ll │ ├── callbr.c │ ├── callbr.ll │ ├── callbr.pre-llvm15.ll │ ├── cmpxchg.c │ ├── cmpxchg.ll │ ├── derivedtype.c │ ├── derivedtype.ll │ ├── di-arg-list.c │ ├── di-arg-list.ll │ ├── di-arg-list.pre-llvm13.ll │ ├── diderivedtype-address-space.at-least-llvm14.ll │ ├── dilocalvariable.ll │ ├── dilocalvariable.pre-llvm14.ll │ ├── factorial2.ll │ ├── fcmp-fast-math.ll │ ├── fn-metadata.ll │ ├── fneg.ll │ ├── fun-attrs.ll │ ├── global-array.ll │ ├── global-var-extern.c │ ├── global-var-extern.ll │ ├── global-var.c │ ├── global-var.ll │ ├── half-float.ll │ ├── hello-world.ll │ ├── insertelt.ll │ ├── instrmd.ll │ ├── localstatic.c │ ├── localstatic.ll │ ├── mutual-struct-rec.ll │ ├── opaque-atomicrmw-uincdecwrap.ll │ ├── opaque-atomicrmw-uincdecwrap.pre-llvm16.ll │ ├── opaque-atomicrmw.ll │ ├── opaque-atomicrmw.pre-llvm15.ll │ ├── opaque-call.ll │ ├── opaque-call.pre-llvm15.ll │ ├── opaque-constant-getelementptr.ll │ ├── opaque-constant-getelementptr.pre-llvm15.ll │ ├── opaque-getelementptr.ll │ ├── opaque-getelementptr.pre-llvm15.ll │ ├── p0.c │ ├── p0.ll │ ├── phi-anon.ll │ ├── poison.ll │ ├── poison.pre-llvm12.ll │ ├── simple-metadata.ll │ ├── simple-res.ll │ ├── smallprog.c │ ├── smallprog.ll │ ├── struct-initializer.ll │ ├── switch-big-value.ll │ ├── switch-same-target.ll │ ├── switch-simple.ll │ └── switch.ll ├── doc └── developing.md ├── examples ├── .gitignore ├── Factorial.hs ├── Makefile └── test.c ├── flake.lock ├── flake.nix ├── fuzzing ├── .gitignore ├── Dockerfile ├── Main.hs ├── README.md ├── fuzz-docker.sh ├── fuzz.sh ├── reduce.sh └── shell.nix ├── llvm-disasm └── LLVMDis.hs ├── llvm-pretty-bc-parser.cabal ├── regression-test ├── Main.hs └── README.md ├── src └── Data │ └── LLVM │ ├── BitCode.hs │ ├── BitCode │ ├── Assert.hs │ ├── BitString.hs │ ├── Bitstream.hs │ ├── GetBits.hs │ ├── IR.hs │ ├── IR │ │ ├── Attrs.hs │ │ ├── Blocks.hs │ │ ├── Constants.hs │ │ ├── Function.hs │ │ ├── Globals.hs │ │ ├── Metadata.hs │ │ ├── Module.hs │ │ ├── Types.hs │ │ └── Values.hs │ ├── Match.hs │ ├── Parse.hs │ └── Record.hs │ ├── CFG.hs │ └── Internal.hs └── unit-test ├── Main.hs └── Tests ├── ExpressionInstances.hs ├── FuncDataInstances.hs ├── Instances.hs ├── Metadata.hs ├── PrimInstances.hs ├── StmtInstances.hs └── TripleInstances.hs /.github/workflows/build.yml: -------------------------------------------------------------------------------- 1 | name: build 2 | on: 3 | workflow_dispatch: 4 | push: 5 | branches: [master, "release-**"] 6 | pull_request: 7 | 8 | env: 9 | # The CACHE_VERSION can be updated to force the use of a new cache if 10 | # the current cache contents become corrupted/invalid. This can 11 | # sometimes happen when (for example) the OS version is changed but 12 | # older .so files are cached, which can have various effects 13 | # (e.g. cabal complains it can't find a valid version of the "happy" 14 | # tool). 15 | CACHE_VERSION: 1 16 | LLVM_VERSION: 12 17 | 18 | jobs: 19 | build: 20 | runs-on: ${{ matrix.os }} 21 | strategy: 22 | fail-fast: true 23 | matrix: 24 | os: [ubuntu-22.04] 25 | # See doc/developing.md 26 | ghc: ["9.4.5", "9.6.2", "9.8.1"] 27 | name: build - ${{ matrix.ghc }} - ${{ matrix.os }} 28 | steps: 29 | - uses: actions/checkout@v2 30 | with: 31 | submodules: true 32 | 33 | - name: Install LLVM (for running tests) 34 | run: | 35 | sudo apt-get -y install llvm-${{ env.LLVM_VERSION }} clang-${{ env.LLVM_VERSION }} 36 | # Inspired by https://gist.github.com/junkdog/70231d6953592cd6f27def59fe19e50d 37 | sudo update-alternatives \ 38 | --install /usr/bin/llvm-config llvm-config /usr/bin/llvm-config-${{ env.LLVM_VERSION }} 100 \ 39 | --slave /usr/bin/llvm-as llvm-as /usr/bin/llvm-as-${{ env.LLVM_VERSION }} \ 40 | --slave /usr/bin/llvm-dis llvm-dis /usr/bin/llvm-dis-${{ env.LLVM_VERSION }} \ 41 | --slave /usr/bin/llvm-link llvm-link /usr/bin/llvm-link-${{ env.LLVM_VERSION }} 42 | # Also run --set, just in case 43 | sudo update-alternatives --set llvm-config /usr/bin/llvm-config-${{ env.LLVM_VERSION }} 44 | # List the installed version as a sanity check 45 | update-alternatives --list llvm-config 46 | 47 | - uses: haskell/actions/setup@v1 48 | id: setup-haskell 49 | with: 50 | ghc-version: ${{ matrix.ghc }} 51 | 52 | - uses: actions/cache/restore@v3 53 | name: Restore cabal store cache 54 | with: 55 | path: | 56 | ${{ steps.setup-haskell.outputs.cabal-store }} 57 | dist-newstyle 58 | key: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ github.sha }} 59 | restore-keys: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}- 60 | 61 | - name: Configure 62 | run: cabal configure --enable-tests -j2 -ffuzz -fregressions 63 | 64 | - name: Build 65 | run: cabal build --enable-tests 66 | 67 | - name: Test 68 | run: | 69 | cabal run unit-test 70 | cabal run disasm-test -- --with-clang /usr/bin/clang-${{ env.LLVM_VERSION }} 71 | 72 | - name: Cabal file check 73 | run: cabal check 74 | 75 | - name: Haddock 76 | run: cabal haddock 77 | 78 | - uses: actions/cache/save@v3 79 | name: Save cabal store cache 80 | if: always() 81 | with: 82 | path: | 83 | ${{ steps.setup-haskell.outputs.cabal-store }} 84 | dist-newstyle 85 | key: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ github.sha }} 86 | -------------------------------------------------------------------------------- /.github/workflows/llvm-quick-fuzz.yml: -------------------------------------------------------------------------------- 1 | name: llvm-quick-fuzz 2 | on: 3 | workflow_dispatch: # i.e. manual activation 4 | # This workflow utilizes a wide range of llvm versions, each of which can be 5 | # installed. When not cached, this could take a long time to run and therefore 6 | # running it nightly (at 3AM) can help ensure it doesn't impact normal 7 | # development. However, notifications of failures are sent to the last person 8 | # that updated this cron syntax portion, or who last enabled the workflow. 9 | # That's pretty inconvenient (and brittle), so now that caching is enabled, 10 | # this is set to be run on approved branches and master merges. 11 | # schedule: 12 | # # * is a special character in YAML so you have to quote this string 13 | # - cron: '* 3 * * *' 14 | 15 | pull_request_review: 16 | types: [submitted] # + github.event.review.state check below 17 | 18 | 19 | env: 20 | # The CACHE_VERSION can be updated to force the use of a new cache if 21 | # the current cache contents become corrupted/invalid. This can 22 | # sometimes happen when (for example) the OS version is changed but 23 | # older .so files are cached, which can have various effects 24 | # (e.g. cabal complains it can't find a valid version of the "happy" 25 | # tool). 26 | CACHE_VERSION: 1 27 | 28 | jobs: 29 | fuzz: 30 | runs-on: ${{ matrix.os }} 31 | if: github.event.review.state == 'approved' 32 | strategy: 33 | fail-fast: false 34 | matrix: 35 | os: [ubuntu-22.04] 36 | # See doc/developing.md 37 | ghc: ["9.2.8"] 38 | llvm: [ "https://github.com/llvm/llvm-project/releases/download/llvmorg-16.0.2/clang+llvm-16.0.2-x86_64-linux-gnu-ubuntu-22.04.tar.xz" 39 | , "https://github.com/llvm/llvm-project/releases/download/llvmorg-15.0.6/clang+llvm-15.0.6-x86_64-linux-gnu-ubuntu-18.04.tar.xz" 40 | , "https://github.com/llvm/llvm-project/releases/download/llvmorg-14.0.0/clang+llvm-14.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz" 41 | , "https://github.com/llvm/llvm-project/releases/download/llvmorg-13.0.0/clang+llvm-13.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz" 42 | , "https://github.com/llvm/llvm-project/releases/download/llvmorg-12.0.0/clang+llvm-12.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz" 43 | , "https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-linux-gnu-ubuntu-20.04.tar.xz" 44 | , "https://github.com/llvm/llvm-project/releases/download/llvmorg-10.0.0/clang+llvm-10.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz" 45 | , "https://releases.llvm.org/9.0.0/clang+llvm-9.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz" 46 | , "https://releases.llvm.org/8.0.0/clang+llvm-8.0.0-x86_64-linux-gnu-ubuntu-18.04.tar.xz" 47 | , "https://releases.llvm.org/7.0.1/clang+llvm-7.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz" 48 | , "https://releases.llvm.org/6.0.1/clang+llvm-6.0.1-x86_64-linux-gnu-ubuntu-16.04.tar.xz" 49 | , "https://releases.llvm.org/5.0.2/clang+llvm-5.0.2-x86_64-linux-gnu-ubuntu-16.04.tar.xz" 50 | , "https://releases.llvm.org/4.0.1/clang+llvm-4.0.1-x86_64-linux-gnu-debian8.tar.xz" 51 | , "https://releases.llvm.org/3.9.0/clang+llvm-3.9.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz" 52 | , "https://releases.llvm.org/3.8.0/clang+llvm-3.8.0-x86_64-linux-gnu-ubuntu-16.04.tar.xz" 53 | , "https://releases.llvm.org/3.7.1/clang+llvm-3.7.1-x86_64-linux-gnu-ubuntu-14.04.tar.xz" 54 | , "https://releases.llvm.org/3.6.2/clang+llvm-3.6.2-x86_64-linux-gnu-ubuntu-14.04.tar.xz" 55 | , "https://releases.llvm.org/3.5.2/clang+llvm-3.5.2-x86_64-linux-gnu-ubuntu-14.04.tar.xz" 56 | ] 57 | name: llvm-quick-fuzz - ${{ matrix.llvm }} 58 | steps: 59 | - uses: actions/checkout@v2 60 | with: 61 | submodules: true 62 | 63 | - uses: haskell/actions/setup@v1 64 | id: setup-haskell 65 | with: 66 | ghc-version: ${{ matrix.ghc }} 67 | 68 | - uses: actions/cache/restore@v3 69 | name: Restore cabal store cache 70 | with: 71 | path: | 72 | ${{ steps.setup-haskell.outputs.cabal-store }} 73 | dist-newstyle 74 | key: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ github.sha }} 75 | restore-keys: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}- 76 | 77 | - shell: bash 78 | run: | 79 | sudo apt-get -y install csmith libcsmith-dev creduce 80 | ln -s /usr/include/csmith $PWD/csmith-include 81 | 82 | - shell: bash 83 | name: Install LLVM 84 | run: | 85 | { curl -sSL ${{ matrix.llvm }} -o llvm.tar.xz && tar xf llvm.tar.xz && mv clang+llvm-* llvm ; } || \ 86 | { curl -sSL ${{ matrix.llvm }} -o llvm.tar.xz && tar xf llvm.tar.xz && mv clang+llvm-* llvm ; } 87 | echo "$PWD/llvm/bin" >> $GITHUB_PATH 88 | 89 | - name: Configure 90 | run: cabal configure --enable-tests -j2 -ffuzz -fregressions 91 | 92 | - shell: bash 93 | name: Build 94 | run: cabal build llvm-disasm fuzz-llvm-disasm 95 | 96 | - shell: bash 97 | run: ln -s $PWD/llvm/bin/clang $PWD/llvm/bin/clangy 98 | 99 | - shell: bash 100 | name: Run fuzzing 101 | run: | 102 | cabal exec fuzz-llvm-disasm -- -n 50 --junit-xml results.xml -o results --collapse --clang-flags="-O -w" --clang-flags="-O -w -g" -c clangy 103 | test $(grep "failures=\"0\"" results.xml | wc -l) -eq 2 104 | env: 105 | CSMITH_PATH: "csmith-include" 106 | 107 | - uses: actions/cache/save@v3 108 | name: Save cabal store cache 109 | if: always() 110 | with: 111 | path: | 112 | ${{ steps.setup-haskell.outputs.cabal-store }} 113 | dist-newstyle 114 | key: ${{ env.CACHE_VERSION }}-cabal-${{ matrix.os }}-${{ matrix.ghc }}-${{ github.sha }} 115 | -------------------------------------------------------------------------------- /.github/workflows/nix-ci.yml: -------------------------------------------------------------------------------- 1 | name: llvm-pretty-bc-parser nix CI 2 | on: 3 | push: 4 | branches: 5 | - 'master' 6 | - 'release-**' 7 | pull_request: 8 | workflow_dispatch: 9 | 10 | jobs: 11 | build: 12 | # This job builds the main package, via a number of GHC versions. This is 13 | # the build that would be used by downstream packages using this as a 14 | # dependency; this does not build documentation or tests. 15 | runs-on: ubuntu-latest 16 | strategy: 17 | matrix: 18 | ghc-version: [ "ghc98", "ghc96", "ghc94" ] 19 | steps: 20 | - uses: cachix/install-nix-action@v20 21 | with: 22 | nix_path: nixpkgs=channel:nixos-23.05 23 | github_access_token: ${{ secrets.GITHUB_TOKEN }} 24 | - uses: cachix/cachix-action@v12 25 | with: 26 | name: galois 27 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 28 | - name: build ${{ matrix.ghc-version }} 29 | shell: bash 30 | run: nix build -L github:${{ github.repository }}/${{ github.sha }}#llvm-pretty-bc-parser.${{ matrix.ghc-version }} 31 | 32 | tests: 33 | # This job builds the tests, and then runs the tests (in two different 34 | # steps). Note that for llvm-pretty-bc-parser, multiple LLVM versions will 35 | # be tested; the actual list of versions is specified in the `flake.nix` file 36 | # used (see the NOTE comment in that file). 37 | runs-on: ubuntu-latest 38 | steps: 39 | - uses: cachix/install-nix-action@v20 40 | with: 41 | nix_path: nixpkgs=channel:nixos-23.05 42 | github_access_token: ${{ secrets.GITHUB_TOKEN }} 43 | - uses: cachix/cachix-action@v12 44 | with: 45 | name: galois 46 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 47 | - name: test build 48 | shell: bash 49 | run: nix build github:${{ github.repository }}/${{ github.sha }}#TESTS_PREP 50 | - name: test 51 | shell: bash 52 | run: nix build -L github:${{ github.repository }}/${{ github.sha }}#TESTS 53 | 54 | doc: 55 | # This job builds the documentation (e.g. Hackage, etc.) 56 | runs-on: ubuntu-latest 57 | steps: 58 | - uses: cachix/install-nix-action@v20 59 | with: 60 | nix_path: nixpkgs=channel:nixos-23.05 61 | github_access_token: ${{ secrets.GITHUB_TOKEN }} 62 | - uses: cachix/cachix-action@v12 63 | with: 64 | name: galois 65 | authToken: '${{ secrets.CACHIX_AUTH_TOKEN }}' 66 | - name: doc 67 | shell: bash 68 | run: nix build github:${{ github.repository }}/${{ github.sha }}#DOC 69 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "llvm-pretty"] 2 | path = llvm-pretty 3 | url = https://github.com/GaloisInc/llvm-pretty.git 4 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Revision history for llvm-pretty-bc-parser 2 | 3 | ## next (TBA) 4 | 5 | Nothing yet. 6 | 7 | ## 0.5.0.0 (March 2025) 8 | 9 | * `Data.LLVM.BitCode` now defines funtions (whose names all end with 10 | `*WithWarnings`) that return any parser-related warnings (`ParseWarning`s) 11 | alongside the parsed `Module`. Users can decide whether or not to display 12 | these warnings (e.g., by printing them to `stderr` using `ppParseWarnings`). 13 | 14 | The existing functions which do not return warnings have been deprecated in 15 | favor of the their `*WithWarnings` variants. 16 | * The functions in `Data.LLVM.BitCode` no longer produce a fatal error when 17 | encountering metadata records of unexpected sizes. Instead, these are now 18 | treated as warnings. 19 | 20 | ## 0.4.2.0 (August 2024) 21 | 22 | * Add support for GHC 9.8 and drop official support of 9.2. 23 | 24 | * Add support for new atomic operations in LLVM 9+. 25 | 26 | ## 0.4.1.0 (January 2024) 27 | 28 | * Add preliminary support for LLVM versions up through 16. 29 | * Require building with `llvm-pretty-0.12.*`. 30 | * Add preliminary support for parsing opaque pointers. For now, 31 | `llvm-pretty-bc-parser` will still fill in the types of certain instructions 32 | with non-opaque pointer types (e.g., the type of memory to store in a `store` 33 | instruction), so be wary of this if you are parsing a bitcode file that 34 | contains opaque pointers. See also the discussion in 35 | https://github.com/GaloisInc/llvm-pretty-bc-parser/issues/262. 36 | * Improve the runtime performance of the parser. 37 | * A variety of bugfixes. Some notable fixes include: 38 | * Fix a bug in which the parser would fail to parse `DIDerivedType` nodes 39 | produced by Apple Clang on macOS. 40 | * Fix a bug in which the DWARF address space field of a `DIDerivedType` node 41 | was parsed incorrectly. 42 | * Fix a bug in which constant `fcmp`/`icmp` expressions would parse their 43 | operands incorrectly. 44 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c)2010, Trevor Elliott 2 | 3 | All rights reserved. 4 | 5 | Redistribution and use in source and binary forms, with or without 6 | modification, are permitted provided that the following conditions are met: 7 | 8 | * Redistributions of source code must retain the above copyright 9 | notice, this list of conditions and the following disclaimer. 10 | 11 | * Redistributions in binary form must reproduce the above 12 | copyright notice, this list of conditions and the following 13 | disclaimer in the documentation and/or other materials provided 14 | with the distribution. 15 | 16 | * Neither the name of Trevor Elliott nor the names of other 17 | contributors may be used to endorse or promote products derived 18 | from this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # llvm-pretty-bc-parser 2 | 3 | A parser for the LLVM bitcode file format, yielding a `Module` from 4 | [the llvm-pretty package](http://hackage.haskell.org/package/llvm-pretty). 5 | 6 | ## Compatibility 7 | 8 | The following table shows what kinds of tests have been/are being run with which 9 | compilers. 10 | 11 | - A check in the the randomized tests column indicates that such tests are 12 | regularly run [in Github Actions][fuzz-workflow]. 13 | - A check in the manual tests column indicates that the parser seems to work on 14 | some code that was generated by this compiler. 15 | 16 | | Compiler | Version | [Randomized tests](./fuzzing) | Manual tests | Notes | 17 | |-----------|---------|-------------------------------|--------------|----------------------| 18 | | `clang` | v3.4 | ✓ | | | 19 | | | v3.5 | ✓ | | | 20 | | | v3.6 | ✓ | | | 21 | | | v3.7 | ✓ | | | 22 | | | v3.8 | ✓ | ✓ | | 23 | | | v3.9 | ✓ | | | 24 | | | v4.0 | ✓ | | | 25 | | | v5.0 | ✓ | | | 26 | | | v6.0 | ✓ | ✓ | | 27 | | | v7.0 | ✓ | | | 28 | | | v8.0 | ✓ | | | 29 | | | v9.0 | ✓ | | | 30 | | | v10.0 | ✓ | | | 31 | | | v11.0 | ✓ | | | 32 | | | v12.0 | ✓ | | | 33 | | | v13.0 | ✓ | | See [issues][llvm13] | 34 | | | v14.0 | ✓ | | See [issues][llvm14] | 35 | | | v15.0 | ✓ | | See [issues][llvm15] | 36 | | | v16.0 | ✓ | | See [issues][llvm16] | 37 | | `clang++` | v3.4 | | | | 38 | | | v3.5 | | | | 39 | | | v3.6 | | | | 40 | | | v3.7 | | | | 41 | | | v3.8 | | | | 42 | | | v3.9 | | | | 43 | | | v4.0 | | | | 44 | | | v5.0 | | | | 45 | | | v6.0 | | | | 46 | | | v7.0 | | ✓ | | 47 | | | v8.0 | | | | 48 | 49 | If you encounter problems with the output of *any* compiler, please file [an 50 | issue](https://github.com/GaloisInc/llvm-pretty-bc-parser/issues). 51 | 52 | ## Documentation 53 | 54 | Developers' documentation: [doc/developing.md](./doc/developing.md) 55 | 56 | ## GHC Support 57 | 58 | llvm-pretty-bc-parser endeavors to support three versions of GHC at a time. See 59 | the developers' documentation for more details and a rationale: 60 | [doc/developing.md](./doc/developing.md). Currently supported: 61 | 62 | - GHC 9.4.5 63 | - GHC 9.6.2 64 | - GHC 9.8.1 65 | 66 | [fuzz-workflow]: https://github.com/GaloisInc/llvm-pretty-bc-parser/blob/master/.github/workflows/llvm-quick-fuzz.yml 67 | [llvm13]: https://github.com/GaloisInc/llvm-pretty-bc-parser/issues?q=is%3Aopen+is%3Aissue+label%3Allvm%2F13.0 68 | [llvm14]: https://github.com/GaloisInc/llvm-pretty-bc-parser/issues?q=is%3Aopen+is%3Aissue+label%3Allvm%2F14.0 69 | [llvm15]: https://github.com/GaloisInc/llvm-pretty-bc-parser/issues?q=is%3Aopen+is%3Aissue+label%3Allvm%2F15.0 70 | [llvm16]: https://github.com/GaloisInc/llvm-pretty-bc-parser/issues?q=is%3Aopen+is%3Aissue+label%3Allvm%2F16.0 71 | -------------------------------------------------------------------------------- /Setup.hs: -------------------------------------------------------------------------------- 1 | import Distribution.Simple 2 | main = defaultMain 3 | -------------------------------------------------------------------------------- /cabal.project: -------------------------------------------------------------------------------- 1 | packages: . 2 | optional-packages: llvm-pretty 3 | constraints: directory >= 1.2.7 4 | -------------------------------------------------------------------------------- /disasm-test/.gitignore: -------------------------------------------------------------------------------- 1 | ghc 2 | runtest 3 | -------------------------------------------------------------------------------- /disasm-test/README.md: -------------------------------------------------------------------------------- 1 | # `disasm-test` 2 | 3 | This test suite ensures that for each `.ll` file under the `tests` directory: 4 | 5 | 1. After using `llvm-as` to produce a `.bc` file, the `.bc` file can be parsed 6 | using `llvm-pretty-bc-parser`. 7 | 2. The resulting `llvm-pretty` AST can be pretty-printed back out to an `.ll` 8 | file using `llvm-pretty`'s pretty-printer. 9 | 3. The new `.ll` file is mostly equivalent to the original `.ll` file. 10 | 11 | Here, "mostly equivalent" means that the two files are syntactically 12 | equivalent, ignoring minor differences in whitespace and the order of metadata 13 | in the metadata list. 14 | 15 | ## Conditional tests 16 | 17 | Some of the test cases have slightly different bitcode depending on which LLVM 18 | version is used. These test cases will have accompanying 19 | `.pre-llvm.ll` files, where `pre-llvm` indicates 20 | that this test output is used for all LLVM versions up to (but not including) 21 | ``. Note that if a test case has multiple `pre-llvm.ll` 22 | files, then the `` that is closest to the current LLVM version 23 | (without going over) is picked. 24 | 25 | To illustrate this with a concrete example, consider suppose we have a test 26 | case `foo` with the following `.ll` files 27 | 28 | * `foo.pre-llvm11.ll` 29 | * `foo.pre-llvm13.ll` 30 | * `foo.ll` 31 | 32 | The following `.ll` files would be used for the following LLVM versions: 33 | 34 | * LLVM 10: `foo.pre-llvm11.ll` 35 | * LLVM 11: `foo.pre-llvm13.ll` 36 | * LLVM 12: `foo.pre-llvm13.ll` 37 | * LLVM 13 or later: `foo.ll` 38 | 39 | There are some test cases that require a sufficiently recent LLVM version to 40 | run. To indicate that a test should not be run on LLVMs older than ``, 41 | create a `pre-llvm.ll` file with `SKIP_TEST` as the first line. The 42 | use of `SKIP_TEST` signals that this test should be skipped when using LLVMs 43 | older than ``. Note that the test suite will not read anything past 44 | `SKIP_TEST`, so the rest of the file can be used to document why the test is 45 | skipped on that particular configuration. 46 | -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/README.md: -------------------------------------------------------------------------------- 1 | This directory contains various LLVM bitcode files that should be used as the 2 | inputs to the `disasm_test` process. 3 | 4 | # Background 5 | 6 | There are multiple types of inputs to disasm_test: 7 | * `.ll` files, which are converted to bitcode files via `llvm-as` 8 | * `C`/`C++` files, which are converted to bitcode files via `clang` 9 | * raw bitcode files, found here. 10 | 11 | As described by disasm-test, once a bitcode file is available, it is converted 12 | back into a text `.ll` format by LLVM's `llvm-dis` and this package's parsing 13 | library + `llvm-pretty` pretty-printing. If that is successful, the resulting 14 | `.ll` file from the second method is used as the new input to repeat the above 15 | process, and the two results are compared for equivalence. 16 | 17 | # This Directory 18 | 19 | The contribution from *this* directory are bitcode-format files that are not--as 20 | part of this testing--generated from a `.ll` or `C` or `C++` file. 21 | 22 | Because the contents of this directory are not human readable (and usually 23 | generated from some other source/toolset), this README should be extended to 24 | include a description of what each bitcode file is intended to test and how it 25 | was generated (even if it wasn't generated locally). 26 | 27 | The tasty-sweet expectations will look in this directory for a `.bc` file as the 28 | root file, with a `.ll` file as the expected file, but (as described in the 29 | Purpose section below), the `.ll` represents the form of the `.bc` that is 30 | obtained via this parsing library (plus `llvm-pretty` pretty-printing) and not 31 | necessarily the original `.bc` file. The contents of the `.ll` files here are as 32 | described in the `disasm-test/README.md`. 33 | 34 | # Purpose 35 | 36 | A primary example of this type of file is a bitcode file generated from Apple's 37 | modified CLANG/LLVM toolset; these files may contain metadata specifications that 38 | are unique to Apple and not merged into the upstream LLVM tools. The 39 | `llvm-pretty-bc-parser` library should be permissive on parsing when it does not 40 | impact the binary code executed, and thus, this library should admit the 41 | Apple-specific bitcode even though the Apple-specific metadata will be dropped. 42 | Since the disasm-test tests run in multiple environments, the actual 43 | bitcode-format files from the Apple toolset is added directly here. 44 | 45 | # Test Manifest 46 | 47 | * `hello-world.bc` : This is a simple test to verify this set of test inputs. It 48 | is actually generated from `hello-world.ll` and should therefore return 49 | success; it represents the benchmark for the other tests collected in this 50 | directory. 51 | 52 | Generated on Linux via: `llvm-as hello-world.ll -o hello-world.bc` 53 | with `llvm-as` version 11.1.0. 54 | -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/apple-llvm.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaloisInc/llvm-pretty-bc-parser/a17a05e874ab0925b29ad2a43d9d5ebb74140df0/disasm-test/bc_src_tests/apple-llvm.bc -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/hello-world.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/GaloisInc/llvm-pretty-bc-parser/a17a05e874ab0925b29ad2a43d9d5ebb74140df0/disasm-test/bc_src_tests/hello-world.bc -------------------------------------------------------------------------------- /disasm-test/bc_src_tests/hello-world.ll: -------------------------------------------------------------------------------- 1 | 2 | define void @hello_world() { 3 | ret void 4 | } 5 | -------------------------------------------------------------------------------- /disasm-test/cpp/.gitignore: -------------------------------------------------------------------------------- 1 | *.bc 2 | *.xml -------------------------------------------------------------------------------- /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/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/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/cpp/generate.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | set -e 4 | 5 | url="https://github.com/NixOS/nixpkgs-channels/archive/nixos-18.03.tar.gz" 6 | 7 | for f in *.cpp; do 8 | nix-shell --pure \ 9 | -p "with import (fetchTarball $url) {}; llvm_6" \ 10 | -p "with import (fetchTarball $url) {}; clang_6" \ 11 | --run "clang++ -O0 -g -emit-llvm -c $f -o ${f%.cpp}.bc && \ 12 | llvm-dis -o ${f%.cpp}.ll ${f%.cpp}.bc && \ 13 | llvm-bcanalyzer -dump ${f%.cpp}.bc > ${f%.cpp}.xml" 14 | done 15 | -------------------------------------------------------------------------------- /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/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/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/cpp/return0.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'return0.bc' 2 | source_filename = "return0.cpp" 3 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | ; Function Attrs: norecurse nounwind readnone sspstrong uwtable 7 | define i32 @main() local_unnamed_addr #0 !dbg !8 { 8 | ret i32 0, !dbg !12 9 | } 10 | 11 | attributes #0 = { norecurse nounwind readnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 12 | 13 | !llvm.dbg.cu = !{!0} 14 | !llvm.module.flags = !{!3, !4, !5, !6} 15 | !llvm.ident = !{!7} 16 | 17 | !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.1 (tags/RELEASE_601/final)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 18 | !1 = !DIFile(filename: "return0.cpp", directory: "/home/siddharthist/code/llvm-pretty-bc-parser/disasm-test/cpp") 19 | !2 = !{} 20 | !3 = !{i32 2, !"Dwarf Version", i32 4} 21 | !4 = !{i32 2, !"Debug Info Version", i32 3} 22 | !5 = !{i32 1, !"wchar_size", i32 4} 23 | !6 = !{i32 7, !"PIC Level", i32 2} 24 | !7 = !{!"clang version 6.0.1 (tags/RELEASE_601/final)"} 25 | !8 = distinct !DISubprogram(name: "main", scope: !1, file: !1, line: 3, type: !9, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !2) 26 | !9 = !DISubroutineType(types: !10) 27 | !10 = !{!11} 28 | !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 29 | !12 = !DILocation(line: 5, column: 3, scope: !8) 30 | -------------------------------------------------------------------------------- /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/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/cpp/templates.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'templates.bc' 2 | source_filename = "templates.cpp" 3 | target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" 4 | target triple = "x86_64-unknown-linux-gnu" 5 | 6 | ; Function Attrs: nounwind readnone sspstrong uwtable 7 | define i32 @nonzeroChar(i8 signext) local_unnamed_addr #0 !dbg !8 { 8 | call void @llvm.dbg.value(metadata i8 %0, metadata !14, metadata !DIExpression()), !dbg !15 9 | call void @llvm.dbg.value(metadata i8 %0, metadata !16, metadata !DIExpression()), !dbg !21 10 | %2 = icmp ne i8 %0, 0, !dbg !23 11 | %3 = zext i1 %2 to i32, !dbg !24 12 | ret i32 %3, !dbg !25 13 | } 14 | 15 | ; Function Attrs: nounwind readnone sspstrong uwtable 16 | define i32 @nonzeroInt(i32) local_unnamed_addr #0 !dbg !26 { 17 | call void @llvm.dbg.value(metadata i32 %0, metadata !30, metadata !DIExpression()), !dbg !31 18 | call void @llvm.dbg.value(metadata i32 %0, metadata !32, metadata !DIExpression()), !dbg !37 19 | %2 = icmp ne i32 %0, 0, !dbg !39 20 | %3 = zext i1 %2 to i32, !dbg !40 21 | ret i32 %3, !dbg !41 22 | } 23 | 24 | ; Function Attrs: nounwind readnone speculatable 25 | declare void @llvm.dbg.value(metadata, metadata, metadata) #1 26 | 27 | attributes #0 = { nounwind readnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 28 | attributes #1 = { nounwind readnone speculatable } 29 | 30 | !llvm.dbg.cu = !{!0} 31 | !llvm.module.flags = !{!3, !4, !5, !6} 32 | !llvm.ident = !{!7} 33 | 34 | !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: !1, producer: "clang version 6.0.1 (tags/RELEASE_601/final)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2) 35 | !1 = !DIFile(filename: "templates.cpp", directory: "/home/siddharthist/code/llvm-pretty-bc-parser/disasm-test/cpp") 36 | !2 = !{} 37 | !3 = !{i32 2, !"Dwarf Version", i32 4} 38 | !4 = !{i32 2, !"Debug Info Version", i32 3} 39 | !5 = !{i32 1, !"wchar_size", i32 4} 40 | !6 = !{i32 7, !"PIC Level", i32 2} 41 | !7 = !{!"clang version 6.0.1 (tags/RELEASE_601/final)"} 42 | !8 = distinct !DISubprogram(name: "nonzeroChar", scope: !1, file: !1, line: 9, type: !9, isLocal: false, isDefinition: true, scopeLine: 9, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !13) 43 | !9 = !DISubroutineType(types: !10) 44 | !10 = !{!11, !12} 45 | !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 46 | !12 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) 47 | !13 = !{!14} 48 | !14 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 9, type: !12) 49 | !15 = !DILocation(line: 9, column: 24, scope: !8) 50 | !16 = !DILocalVariable(name: "a", arg: 1, scope: !17, file: !1, line: 4, type: !12) 51 | !17 = distinct !DISubprogram(name: "nonzero", linkageName: "_Z7nonzeroIcEiT_", scope: !1, file: !1, line: 4, type: !9, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !19, variables: !18) 52 | !18 = !{!16} 53 | !19 = !{!20} 54 | !20 = !DITemplateTypeParameter(name: "T", type: !12) 55 | !21 = !DILocation(line: 4, column: 15, scope: !17, inlinedAt: !22) 56 | !22 = distinct !DILocation(line: 9, column: 36, scope: !8) 57 | !23 = !DILocation(line: 5, column: 12, scope: !17, inlinedAt: !22) 58 | !24 = !DILocation(line: 5, column: 10, scope: !17, inlinedAt: !22) 59 | !25 = !DILocation(line: 9, column: 29, scope: !8) 60 | !26 = distinct !DISubprogram(name: "nonzeroInt", scope: !1, file: !1, line: 10, type: !27, isLocal: false, isDefinition: true, scopeLine: 10, flags: DIFlagPrototyped, isOptimized: true, unit: !0, variables: !29) 61 | !27 = !DISubroutineType(types: !28) 62 | !28 = !{!11, !11} 63 | !29 = !{!30} 64 | !30 = !DILocalVariable(name: "a", arg: 1, scope: !26, file: !1, line: 10, type: !11) 65 | !31 = !DILocation(line: 10, column: 22, scope: !26) 66 | !32 = !DILocalVariable(name: "a", arg: 1, scope: !33, file: !1, line: 4, type: !11) 67 | !33 = distinct !DISubprogram(name: "nonzero", linkageName: "_Z7nonzeroIiEiT_", scope: !1, file: !1, line: 4, type: !27, isLocal: false, isDefinition: true, scopeLine: 4, flags: DIFlagPrototyped, isOptimized: true, unit: !0, templateParams: !35, variables: !34) 68 | !34 = !{!32} 69 | !35 = !{!36} 70 | !36 = !DITemplateTypeParameter(name: "T", type: !11) 71 | !37 = !DILocation(line: 4, column: 15, scope: !33, inlinedAt: !38) 72 | !38 = distinct !DILocation(line: 10, column: 34, scope: !26) 73 | !39 = !DILocation(line: 5, column: 12, scope: !33, inlinedAt: !38) 74 | !40 = !DILocation(line: 5, column: 10, scope: !33, inlinedAt: !38) 75 | !41 = !DILocation(line: 10, column: 27, scope: !26) 76 | -------------------------------------------------------------------------------- /disasm-test/failing/global.ll: -------------------------------------------------------------------------------- 1 | @value = global i32 10 2 | -------------------------------------------------------------------------------- /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/known_bugs/README.md: -------------------------------------------------------------------------------- 1 | # Known Bugs for llvm-pretty-bc-parser 2 | 3 | This directory is used to keep files for known llvm-pretty-bc-parser bugs. The 4 | goal is that this directory is empty (other than this readme), but the reality is 5 | that sometimes there are issues that will take some time to address. 6 | 7 | If an entry is made in this directory, corresponding tests will be *expected* to 8 | fail, and thus the entire CI test suite will pass even in the presence of these 9 | bugs. This is more desirable than either (a) adding tests to demonstrate the bug 10 | but then having to "ignore" test failures manually, and (b) not adding tests to 11 | the test suite for known bugs because it is desireable or required that the CI 12 | passes. With this mechanism, a test should be added to demonstrate the problem 13 | (and an issue should be filed!) but the CI can regain the previous state until 14 | the bugs can be addressed (because this library does not define original 15 | functionality, but it recapitulates functionality from the LLVM project). Also 16 | note that any efforts that add *new* capabilities are not expected to create 17 | entries in this directory: they should be fully and successfully implemented if 18 | at all possible before merging into mainline code. 19 | 20 | # Format 21 | 22 | When adding a new entry to this directory, a single file is created. By using a 23 | single file, known bugs can be added and removed easily without the necessity of 24 | code changes elsewhere (and keeping the list of known bugs in source code invites 25 | the potential for merge conflicts when adding/resolving bugs in parallel efforts, 26 | whereas these separate files do not). 27 | 28 | All files in this directory are processed (including this one!), regardless of 29 | filename or extension. Only files which contain marker lines (described below) 30 | will be added as a known bug; this file describes marker lines but is careful to 31 | not contain marker lines (i.e. a line which begins with `"##>"`), so that it will 32 | not be treated as a known bug. 33 | 34 | Lines which begin with `"##> rootMatchName: "` should be followed by one or 35 | more words which correspond to the corresponding tasty-sugar field in the 36 | provided `Sweets` structure when generating tests. 37 | 38 | Lines which begin with `"##> llvmver: "` should be followed by one or more words, 39 | each of which corresponds to an llvm version (in numeric format, e.g. `10` `11` 40 | `4`) that the bug is known to be present for. 41 | 42 | The above lines are the primary mechanism for matching a particular test with the 43 | expectation that it will fail. There can be multiple values specified after each 44 | identifier word, and there can be multiple lines starting with each word: all 45 | corresponding tasty-sugar sweets will be identified as failures. There must be 46 | at least one identifier line present, but any identifier lines not present will 47 | be treated as a wildcard. 48 | 49 | One and only one line should start with `"##> summary: "`; the remainder of 50 | that line is displayed along with the (expected) failure message when running the 51 | test. 52 | 53 | All other lines in the file are ignored by disasm-test. It is recommended that 54 | the file contain additional information, including how to reproduce the issue, 55 | how to recognize the issue, links to actual issues (e.g. posted to GitHub) and 56 | any thoughts regarding the potential cause of the issue. This information can be 57 | helpful to whomever attempts to resolve this known bug (where success will be 58 | indicated by the ability to remove this corresponding known_bugs file). 59 | -------------------------------------------------------------------------------- /disasm-test/known_bugs/llvm_dbg_declare_inline: -------------------------------------------------------------------------------- 1 | ##> rootMatchName: localstatic.c 2 | ##> rootMatchName: localstatic.ll 3 | ##> summary: llvm.dbg.declare should use md refs and not inline 4 | 5 | Logged in https://github.com/GaloisInc/llvm-pretty-bc-parser/issues/260 6 | 7 | Attempts to inline declare the !DILocalVariable for the file-local static: 8 | 9 | call void @llvm.dbg.declare(metadata i32* %2, metadata !DILocalVariable(scope: !DISubprogram(scope: !3, name: "has_local_static", file: !3, line: 5, type: !9, isLocal: false, isDefinition: true, scopeLine: 5, virtuality: 0, virtualIndex: 0, flags: 256, isOptimized: false, unit: !2, retainedNodes: !4), name: "x", file: !DIFile(filename: "localstatic.c", directory: "/home/kquick/work/DFAMS/tp241209/sources/llvm-pretty-bc-parser/disasm-test/tests"), line: 5, type: !DIBasicType(tag: 36, name: "int", size: 32, align: 0, encoding: 5, flags: 0), arg: 1, flags: 0, align: 0), metadata !DIExpression()), !dbg !DILocation(line: 5, column: 26, scope: !0) 10 | 11 | , but llvm-as rejects that: 12 | 13 | llvm-as: file.ll:L:C: error: missing 'distinct', required for !DISubprogram that is a Definition 14 | 15 | Adding 'distinct' in various places on the line does not work 16 | 17 | The llvm-dis handles this as: 18 | 19 | call void @llvm.dbg.declare(metadata i32* %2, metadata !21, metadata !DIExpression()), !dbg !22 20 | 21 | where: 22 | 23 | !2 = distinct !DISubprogram(name: "has_local_static", scope: !3, file: !3, line: 5, type: !4, scopeLine: 5, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !7, retainedNodes: !8) 24 | !21 = !DILocalVariable(name: "x", arg: 1, scope: !2, file: !3, line: 5, type: !6) 25 | 26 | Note that for the llvm-disasm version, we do have: 27 | 28 | !0 = distinct !DISubprogram(scope: !3, name: "has_local_static", file: !3, line: 5, type: !9, isLocal: false, isDefinition: true, scopeLine: 5, virtuality: 0, virtualIndex: 0, flags: 256, isOptimized: false, unit: !2, retainedNodes: !4) 29 | !21 = !DILocalVariable(scope: !0, name: "x", file: !3, line: 5, type: !7, arg: 1, flags: 0, align: 0) 30 | 31 | So apparently it is mostly needed to have the llvm.dbg.declare use the UnnamedMd 32 | indices (if available) rather than inlining them. -------------------------------------------------------------------------------- /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/llvm-tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.bc -------------------------------------------------------------------------------- /disasm-test/llvm-tests/LICENSE: -------------------------------------------------------------------------------- 1 | ============================================================================== 2 | LLVM Release License 3 | ============================================================================== 4 | University of Illinois/NCSA 5 | Open Source License 6 | 7 | Copyright (c) 2003-2018 University of Illinois at Urbana-Champaign. 8 | All rights reserved. 9 | 10 | Developed by: 11 | 12 | LLVM Team 13 | 14 | University of Illinois at Urbana-Champaign 15 | 16 | http://llvm.org 17 | 18 | Permission is hereby granted, free of charge, to any person obtaining a copy of 19 | this software and associated documentation files (the "Software"), to deal with 20 | the Software without restriction, including without limitation the rights to 21 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 22 | of the Software, and to permit persons to whom the Software is furnished to do 23 | so, subject to the following conditions: 24 | 25 | * Redistributions of source code must retain the above copyright notice, 26 | this list of conditions and the following disclaimers. 27 | 28 | * Redistributions in binary form must reproduce the above copyright notice, 29 | this list of conditions and the following disclaimers in the 30 | documentation and/or other materials provided with the distribution. 31 | 32 | * Neither the names of the LLVM Team, University of Illinois at 33 | Urbana-Champaign, nor the names of its contributors may be used to 34 | endorse or promote products derived from this Software without specific 35 | prior written permission. 36 | 37 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 38 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 39 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 40 | CONTRIBUTORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 41 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 42 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE 43 | SOFTWARE. 44 | 45 | ============================================================================== 46 | Copyrights and Licenses for Third Party Software Distributed with LLVM: 47 | ============================================================================== 48 | The LLVM software contains code written by third parties. Such software will 49 | have its own individual LICENSE.TXT file in the directory in which it appears. 50 | This file will describe the copyrights, license, and restrictions which apply 51 | to that code. 52 | 53 | The disclaimer of warranty in the University of Illinois Open Source License 54 | applies to all code in the LLVM Distribution, and nothing in any of the 55 | other licenses gives permission to use the names of the LLVM Team or the 56 | University of Illinois to endorse or promote products derived from this 57 | Software. 58 | 59 | The following pieces of software have additional or alternate copyrights, 60 | licenses, and/or restrictions: 61 | 62 | Program Directory 63 | ------- --------- 64 | Google Test llvm/utils/unittest/googletest 65 | OpenBSD regex llvm/lib/Support/{reg*, COPYRIGHT.regex} 66 | pyyaml tests llvm/test/YAMLParser/{*.data, LICENSE.TXT} 67 | ARM contributions llvm/lib/Target/ARM/LICENSE.TXT 68 | md5 contributions llvm/lib/Support/MD5.cpp llvm/include/llvm/Support/MD5.h 69 | -------------------------------------------------------------------------------- /disasm-test/llvm-tests/README.md: -------------------------------------------------------------------------------- 1 | # Tests from the LLVM project 2 | 3 | The tests in this directory are taken from the LLVM project. See [LICENSE](./LICENSE) 4 | (taken from [the LLVM project source](https://raw.githubusercontent.com/llvm-mirror/llvm/master/LICENSE.TXT)). 5 | 6 | Some of these files don't assemble unless used with the corresponding version 7 | of `llvm-as`. 8 | 9 | - File: `mdnodes-distinct-nodes-first.ll` 10 | + Path in LLVM source tree: `test/Bitcode/mdnodes-distinct-nodes-first.ll` 11 | + 12 | Revision checked out of tree: [e7a2c97](https://github.com/llvm-mirror/llvm/commit/e7a2c97bc25b03f13046949bd767a8207f774cf7) 13 | + Corresponding LLVM release: 3.9 14 | + Purpose: `llvm-disasm` doesn't faithfully reproduce the functionality of _any_ 15 | version of `llvm-dis` on this example. 16 | 17 | - File: `cfi-eof-prologue.new.ll` 18 | + Path in LLVM source tree: `test/DebugInfo/AArch64/cfi-eof-prologue.ll` 19 | + 20 | Revision checked out of tree: [de74840](https://github.com/llvm-mirror/llvm/blob/de7484036b628b08be6acbfb5feac405d7450300) 21 | + Corresponding LLVM release: 3.9 22 | + Purpose: References to `DICompositeType`s changed in 3.9. See 23 | [llvm-pretty#39](https://github.com/GaloisInc/llvm-pretty/issues/39). 24 | 25 | - File: `cfi-eof-prologue.old.ll` 26 | + Path in LLVM source tree: `test/DebugInfo/AArch64/cfi-eof-prologue.ll` 27 | + Revision checked out of tree: [release_38](https://github.com/llvm-mirror/llvm/blob/release_38/) 28 | + Corresponding LLVM release: 3.8 29 | + Purpose: See above. We should also maintain compatibility with 3.8-style 30 | references. 31 | -------------------------------------------------------------------------------- /disasm-test/llvm-tests/cfi-eof-prologue.new.ll: -------------------------------------------------------------------------------- 1 | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 2 | target triple = "aarch64-apple-ios" 3 | 4 | %struct.B = type { %struct.A } 5 | %struct.A = type { i32 (...)** } 6 | 7 | @_ZTV1B = external unnamed_addr constant [4 x i8*] 8 | 9 | ; Function Attrs: nounwind 10 | define %struct.B* @_ZN1BC2Ev(%struct.B* %this) unnamed_addr #0 align 2 !dbg !28 { 11 | entry: 12 | tail call void @llvm.dbg.value(metadata %struct.B* %this, i64 0, metadata !30, metadata !38), !dbg !39 13 | %0 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, !dbg !40 14 | %call = tail call %struct.A* @_ZN1AC2Ev(%struct.A* %0) #3, !dbg !40 15 | %1 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, i32 0, !dbg !40 16 | store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**), i32 (...)*** %1, align 8, !dbg !40, !tbaa !41 17 | ret %struct.B* %this, !dbg !40 18 | } 19 | 20 | declare %struct.A* @_ZN1AC2Ev(%struct.A*) 21 | 22 | ; Function Attrs: nounwind 23 | define %struct.B* @_ZN1BC1Ev(%struct.B* %this) unnamed_addr #0 align 2 !dbg !32 { 24 | entry: 25 | tail call void @llvm.dbg.value(metadata %struct.B* %this, i64 0, metadata !34, metadata !38), !dbg !44 26 | tail call void @llvm.dbg.value(metadata %struct.B* %this, i64 0, metadata !45, metadata !38) #3, !dbg !47 27 | %0 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, !dbg !48 28 | %call.i = tail call %struct.A* @_ZN1AC2Ev(%struct.A* %0) #3, !dbg !48 29 | %1 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, i32 0, !dbg !48 30 | store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**), i32 (...)*** %1, align 8, !dbg !48, !tbaa !41 31 | ret %struct.B* %this, !dbg !46 32 | } 33 | 34 | ; Function Attrs: nounwind readnone 35 | declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 36 | 37 | attributes #0 = { nounwind } 38 | attributes #2 = { nounwind readnone } 39 | attributes #3 = { nounwind } 40 | 41 | !llvm.dbg.cu = !{!0} 42 | !llvm.module.flags = !{!35, !36} 43 | !llvm.ident = !{!37} 44 | 45 | !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 (trunk 224279) (llvm/trunk 224283)", isOptimized: true, emissionKind: FullDebug, file: !1, enums: !2, retainedTypes: !3, globals: !2, imports: !2) 46 | !1 = !DIFile(filename: "", directory: "") 47 | !2 = !{} 48 | !3 = !{!4, !13} 49 | !4 = !DICompositeType(tag: DW_TAG_structure_type, name: "B", line: 5, size: 64, align: 64, file: !5, elements: !6, vtableHolder: !13, identifier: "_ZTS1B") 50 | !5 = !DIFile(filename: "test1.cpp", directory: "") 51 | !6 = !{!7, !8, !12} 52 | !7 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !4, baseType: !13) 53 | !8 = !DISubprogram(name: "B", line: 6, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 6, file: !5, scope: !4, type: !9) 54 | !9 = !DISubroutineType(types: !10) 55 | !10 = !{null, !11} 56 | !11 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !4) 57 | !12 = !DISubprogram(name: "~B", line: 7, isLocal: false, isDefinition: false, virtuality: DW_VIRTUALITY_virtual, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 7, file: !5, scope: !4, type: !9, containingType: !4) 58 | !13 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", line: 1, size: 64, align: 64, file: !5, elements: !14, vtableHolder: !13, identifier: "_ZTS1A") 59 | !14 = !{!15, !22, !26} 60 | !15 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$A", size: 64, flags: DIFlagArtificial, file: !5, scope: !16, baseType: !17) 61 | !16 = !DIFile(filename: "test1.cpp", directory: "") 62 | !17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, baseType: !18) 63 | !18 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", size: 64, baseType: !19) 64 | !19 = !DISubroutineType(types: !20) 65 | !20 = !{!21} 66 | !21 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) 67 | !22 = !DISubprogram(name: "A", line: 2, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 2, file: !5, scope: !13, type: !23) 68 | !23 = !DISubroutineType(types: !24) 69 | !24 = !{null, !25} 70 | !25 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !13) 71 | !26 = !DISubprogram(name: "~A", line: 3, isLocal: false, isDefinition: false, virtuality: DW_VIRTUALITY_virtual, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 3, file: !5, scope: !13, type: !23, containingType: !13) 72 | !28 = distinct !DISubprogram(name: "B", linkageName: "_ZN1BC2Ev", line: 9, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 9, file: !5, scope: !4, type: !9, declaration: !8, variables: !29) 73 | !29 = !{!30} 74 | !30 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !28, type: !31) 75 | !31 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !4) 76 | !32 = distinct !DISubprogram(name: "B", linkageName: "_ZN1BC1Ev", line: 9, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, unit: !0, scopeLine: 9, file: !5, scope: !4, type: !9, declaration: !8, variables: !33) 77 | !33 = !{!34} 78 | !34 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !32, type: !31) 79 | !35 = !{i32 2, !"Dwarf Version", i32 4} 80 | !36 = !{i32 2, !"Debug Info Version", i32 3} 81 | !37 = !{!"clang version 3.6.0 (trunk 224279) (llvm/trunk 224283)"} 82 | !38 = !DIExpression() 83 | !39 = !DILocation(line: 0, scope: !28) 84 | !40 = !DILocation(line: 9, scope: !28) 85 | !41 = !{!42, !42, i64 0} 86 | !42 = !{!"vtable pointer", !43, i64 0} 87 | !43 = !{!"Simple C/C++ TBAA"} 88 | !44 = !DILocation(line: 0, scope: !32) 89 | !45 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !28, type: !31) 90 | !46 = !DILocation(line: 9, scope: !32) 91 | !47 = !DILocation(line: 0, scope: !28, inlinedAt: !46) 92 | !48 = !DILocation(line: 9, scope: !28, inlinedAt: !46) 93 | -------------------------------------------------------------------------------- /disasm-test/llvm-tests/cfi-eof-prologue.old.ll: -------------------------------------------------------------------------------- 1 | ; struct A { 2 | ; A(); 3 | ; virtual ~A(); 4 | ; }; 5 | ; struct B : A { 6 | ; B(); 7 | ; virtual ~B(); 8 | ; }; 9 | ; B::B() {} 10 | ; CHECK: __ZN1BC1Ev: 11 | ; CHECK: .loc 1 [[@LINE-2]] 0 prologue_end 12 | ; CHECK-NOT: .loc 1 0 0 prologue_end 13 | 14 | ; The location of the prologue_end marker should not be affected by the presence 15 | ; of CFI instructions. 16 | 17 | ; RUN: llc -O0 -filetype=asm < %s | FileCheck %s 18 | 19 | ; ModuleID = 'test1.cpp' 20 | target datalayout = "e-m:o-i64:64-i128:128-n32:64-S128" 21 | target triple = "aarch64-apple-ios" 22 | 23 | %struct.B = type { %struct.A } 24 | %struct.A = type { i32 (...)** } 25 | 26 | @_ZTV1B = external unnamed_addr constant [4 x i8*] 27 | 28 | ; Function Attrs: nounwind 29 | define %struct.B* @_ZN1BC2Ev(%struct.B* %this) unnamed_addr #0 align 2 !dbg !28 { 30 | entry: 31 | tail call void @llvm.dbg.value(metadata %struct.B* %this, i64 0, metadata !30, metadata !38), !dbg !39 32 | %0 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, !dbg !40 33 | %call = tail call %struct.A* @_ZN1AC2Ev(%struct.A* %0) #3, !dbg !40 34 | %1 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, i32 0, !dbg !40 35 | store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**), i32 (...)*** %1, align 8, !dbg !40, !tbaa !41 36 | ret %struct.B* %this, !dbg !40 37 | } 38 | 39 | declare %struct.A* @_ZN1AC2Ev(%struct.A*) 40 | 41 | ; Function Attrs: nounwind 42 | define %struct.B* @_ZN1BC1Ev(%struct.B* %this) unnamed_addr #0 align 2 !dbg !32 { 43 | entry: 44 | tail call void @llvm.dbg.value(metadata %struct.B* %this, i64 0, metadata !34, metadata !38), !dbg !44 45 | tail call void @llvm.dbg.value(metadata %struct.B* %this, i64 0, metadata !45, metadata !38) #3, !dbg !47 46 | %0 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, !dbg !48 47 | %call.i = tail call %struct.A* @_ZN1AC2Ev(%struct.A* %0) #3, !dbg !48 48 | %1 = getelementptr inbounds %struct.B, %struct.B* %this, i64 0, i32 0, i32 0, !dbg !48 49 | store i32 (...)** bitcast (i8** getelementptr inbounds ([4 x i8*], [4 x i8*]* @_ZTV1B, i64 0, i64 2) to i32 (...)**), i32 (...)*** %1, align 8, !dbg !48, !tbaa !41 50 | ret %struct.B* %this, !dbg !46 51 | } 52 | 53 | ; Function Attrs: nounwind readnone 54 | declare void @llvm.dbg.value(metadata, i64, metadata, metadata) #2 55 | 56 | attributes #0 = { nounwind } 57 | attributes #2 = { nounwind readnone } 58 | attributes #3 = { nounwind } 59 | 60 | !llvm.dbg.cu = !{!0} 61 | !llvm.module.flags = !{!35, !36} 62 | !llvm.ident = !{!37} 63 | 64 | !0 = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, producer: "clang version 3.6.0 (trunk 224279) (llvm/trunk 224283)", isOptimized: true, emissionKind: 1, file: !1, enums: !2, retainedTypes: !3, subprograms: !27, globals: !2, imports: !2) 65 | !1 = !DIFile(filename: "", directory: "") 66 | !2 = !{} 67 | !3 = !{!4, !13} 68 | !4 = !DICompositeType(tag: DW_TAG_structure_type, name: "B", line: 5, size: 64, align: 64, file: !5, elements: !6, vtableHolder: !"_ZTS1A", identifier: "_ZTS1B") 69 | !5 = !DIFile(filename: "test1.cpp", directory: "") 70 | !6 = !{!7, !8, !12} 71 | !7 = !DIDerivedType(tag: DW_TAG_inheritance, scope: !"_ZTS1B", baseType: !"_ZTS1A") 72 | !8 = !DISubprogram(name: "B", line: 6, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 6, file: !5, scope: !"_ZTS1B", type: !9) 73 | !9 = !DISubroutineType(types: !10) 74 | !10 = !{null, !11} 75 | !11 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1B") 76 | !12 = !DISubprogram(name: "~B", line: 7, isLocal: false, isDefinition: false, virtuality: DW_VIRTUALITY_virtual, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 7, file: !5, scope: !"_ZTS1B", type: !9, containingType: !"_ZTS1B") 77 | !13 = !DICompositeType(tag: DW_TAG_structure_type, name: "A", line: 1, size: 64, align: 64, file: !5, elements: !14, vtableHolder: !"_ZTS1A", identifier: "_ZTS1A") 78 | !14 = !{!15, !22, !26} 79 | !15 = !DIDerivedType(tag: DW_TAG_member, name: "_vptr$A", size: 64, flags: DIFlagArtificial, file: !5, scope: !16, baseType: !17) 80 | !16 = !DIFile(filename: "test1.cpp", directory: "") 81 | !17 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, baseType: !18) 82 | !18 = !DIDerivedType(tag: DW_TAG_pointer_type, name: "__vtbl_ptr_type", size: 64, baseType: !19) 83 | !19 = !DISubroutineType(types: !20) 84 | !20 = !{!21} 85 | !21 = !DIBasicType(tag: DW_TAG_base_type, name: "int", size: 32, align: 32, encoding: DW_ATE_signed) 86 | !22 = !DISubprogram(name: "A", line: 2, isLocal: false, isDefinition: false, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 2, file: !5, scope: !"_ZTS1A", type: !23) 87 | !23 = !DISubroutineType(types: !24) 88 | !24 = !{null, !25} 89 | !25 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, flags: DIFlagArtificial | DIFlagObjectPointer, baseType: !"_ZTS1A") 90 | !26 = !DISubprogram(name: "~A", line: 3, isLocal: false, isDefinition: false, virtuality: DW_VIRTUALITY_virtual, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 3, file: !5, scope: !"_ZTS1A", type: !23, containingType: !"_ZTS1A") 91 | !27 = !{!28, !32} 92 | !28 = distinct !DISubprogram(name: "B", linkageName: "_ZN1BC2Ev", line: 9, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 9, file: !5, scope: !"_ZTS1B", type: !9, declaration: !8, variables: !29) 93 | !29 = !{!30} 94 | !30 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !28, type: !31) 95 | !31 = !DIDerivedType(tag: DW_TAG_pointer_type, size: 64, align: 64, baseType: !"_ZTS1B") 96 | !32 = distinct !DISubprogram(name: "B", linkageName: "_ZN1BC1Ev", line: 9, isLocal: false, isDefinition: true, flags: DIFlagPrototyped, isOptimized: true, scopeLine: 9, file: !5, scope: !"_ZTS1B", type: !9, declaration: !8, variables: !33) 97 | !33 = !{!34} 98 | !34 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !32, type: !31) 99 | !35 = !{i32 2, !"Dwarf Version", i32 4} 100 | !36 = !{i32 2, !"Debug Info Version", i32 3} 101 | !37 = !{!"clang version 3.6.0 (trunk 224279) (llvm/trunk 224283)"} 102 | !38 = !DIExpression() 103 | !39 = !DILocation(line: 0, scope: !28) 104 | !40 = !DILocation(line: 9, scope: !28) 105 | !41 = !{!42, !42, i64 0} 106 | !42 = !{!"vtable pointer", !43, i64 0} 107 | !43 = !{!"Simple C/C++ TBAA"} 108 | !44 = !DILocation(line: 0, scope: !32) 109 | !45 = !DILocalVariable(name: "this", arg: 1, flags: DIFlagArtificial | DIFlagObjectPointer, scope: !28, type: !31) 110 | !46 = !DILocation(line: 9, scope: !32) 111 | !47 = !DILocation(line: 0, scope: !28, inlinedAt: !46) 112 | !48 = !DILocation(line: 9, scope: !28, inlinedAt: !46) 113 | -------------------------------------------------------------------------------- /disasm-test/llvm-tests/mdnodes-distinct-nodes-first.ll: -------------------------------------------------------------------------------- 1 | ; RUN: llvm-as <%s | llvm-bcanalyzer -dump | FileCheck %s 2 | ; Check that distinct nodes are emitted before uniqued nodes, even if that 3 | ; breaks post-order traversals. 4 | 5 | ; Nodes in this testcase are numbered to match how they are referenced in 6 | ; bitcode. !1 is referenced as opN=1. 7 | 8 | ; CHECK: 9 | !1 = distinct !{!2} 10 | 11 | ; CHECK-NEXT: 12 | !2 = !{!1} 13 | 14 | ; Note: named metadata nodes are not cannot reference null so their operands 15 | ; are numbered off-by-one. 16 | ; CHECK-NEXT: 18 | !named = !{!2} 19 | -------------------------------------------------------------------------------- /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/tests/T189.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'T189.c' 2 | source_filename = "T189.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-pc-linux-gnu" 5 | 6 | @.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 7 | 8 | ; Function Attrs: noinline nounwind optnone uwtable 9 | define dso_local void @f() #0 { 10 | entry: 11 | %p = alloca i32 (i8*, ...)*, align 8 12 | store i32 (i8*, ...)* @printf, i32 (i8*, ...)** %p, align 8 13 | %0 = load i32 (i8*, ...)*, i32 (i8*, ...)** %p, align 8 14 | %call = call i32 (i8*, ...) %0(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 0) 15 | ret void 16 | } 17 | 18 | declare dso_local i32 @printf(i8*, ...) #1 19 | 20 | attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 21 | attributes #1 = { "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 22 | 23 | !llvm.module.flags = !{!0} 24 | !llvm.ident = !{!1} 25 | !llvm.commandline = !{!2} 26 | 27 | !0 = !{i32 1, !"wchar_size", i32 4} 28 | !1 = !{!"clang version 10.0.0-4ubuntu1 "} 29 | !2 = !{!"/usr/lib/llvm-10/bin/clang -S -emit-llvm -frecord-command-line -fno-discard-value-names T189.c -o T189.ll"} 30 | -------------------------------------------------------------------------------- /disasm-test/tests/T266-constant-icmp.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/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/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-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/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-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/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/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/atomicrmw.ll: -------------------------------------------------------------------------------- 1 | define void @atomicrmw(i32* %a, i32 %i) { 2 | %b0 = atomicrmw xchg i32* %a, i32 %i acquire 3 | %b1 = atomicrmw add i32* %a, i32 %i acquire 4 | %b2 = atomicrmw sub i32* %a, i32 %i acquire 5 | %b3 = atomicrmw and i32* %a, i32 %i acquire 6 | %b4 = atomicrmw nand i32* %a, i32 %i acquire 7 | %b5 = atomicrmw or i32* %a, i32 %i acquire 8 | %b6 = atomicrmw xor i32* %a, i32 %i acquire 9 | %b7 = atomicrmw max i32* %a, i32 %i acquire 10 | %b8 = atomicrmw min i32* %a, i32 %i acquire 11 | %b9 = atomicrmw umax i32* %a, i32 %i acquire 12 | %b10 = atomicrmw umin i32* %a, i32 %i acquire 13 | ret void 14 | } 15 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-dicompositetype.ll: -------------------------------------------------------------------------------- 1 | ;; https://github.com/llvm/llvm-project/blob/0b32dca12ef4d82af71f86a70c49806e5b81ead2/llvm/test/Bitcode/attr-btf_tag-dicomposite.ll 2 | 3 | !3 = !DIFile(filename: "struct.c", directory: "/home/yhs/work/tests/llvm/btf_tag") 4 | !6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t", file: !3, line: 1, size: 32, elements: !7, annotations: !10) 5 | !7 = !{!8} 6 | !8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !3, line: 1, baseType: !9, size: 32) 7 | !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 8 | !10 = !{!11, !12} 9 | !11 = !{!"btf_tag", !"a"} 10 | !12 = !{!"btf_tag", !"b"} 11 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-dicompositetype.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-diderivedtype.ll: -------------------------------------------------------------------------------- 1 | ;; Adapted from https://github.com/llvm/llvm-project/blob/430e22388173c96da6777fccb9735a6e8ee3ea1c/llvm/test/Bitcode/attr-btf_tag-field.ll 2 | 3 | !1 = !DIFile(filename: "attr-btf_tag-field.c", directory: "/home/yhs/work/tests/llvm/btf_tag") 4 | !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 5 | !14 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !1, line: 7, size: 32, elements: !15) 6 | !15 = !{!16} 7 | !16 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !14, file: !1, line: 8, baseType: !12, size: 32, annotations: !17) 8 | !17 = !{!18, !19} 9 | !18 = !{!"btf_tag", !"tag1"} 10 | !19 = !{!"btf_tag", !"tag2"} 11 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-diderivedtype.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-diglobalvariable.ll: -------------------------------------------------------------------------------- 1 | ;; Adapted from https://github.com/llvm/llvm-project/blob/30c288489ae51a3e0819241f367eeae6df2b09e7/llvm/test/Bitcode/attr-btf_tag-diglobalvariable.ll 2 | 3 | !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) 4 | !1 = distinct !DIGlobalVariable(name: "g1", scope: !2, file: !3, line: 7, type: !6, isLocal: false, isDefinition: true, annotations: !10) 5 | !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git 47af5574a87dc298b5c6c36ff6a969c8c77c8499)", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) 6 | !3 = !DIFile(filename: "t.c", directory: "/home/yhs/work/tests/llvm/btf_tag") 7 | !4 = !{} 8 | !5 = !{!0} 9 | !6 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1", file: !3, line: 4, size: 32, elements: !7) 10 | !7 = !{!8} 11 | !8 = !DIDerivedType(tag: DW_TAG_member, name: "a", scope: !6, file: !3, line: 5, baseType: !9, size: 32) 12 | !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 13 | !10 = !{!11, !12} 14 | !11 = !{!"btf_tag", !"tag1"} 15 | !12 = !{!"btf_tag", !"tag2"} 16 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-diglobalvariable.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-dilocalvariable.ll: -------------------------------------------------------------------------------- 1 | ;; Adapted from https://github.com/llvm/llvm-project/blob/1bebc31c617d1a0773f1d561f02dd17c5e83b23b/llvm/test/Bitcode/attr-btf_tag-parameter.ll 2 | 3 | !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git c9e3139e00bcef23b236a02890b909a130d1b3d9)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) 4 | !1 = !DIFile(filename: "func.c", directory: "/home/yhs/work/tests/llvm/btf_tag") 5 | !2 = !{} 6 | !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12) 7 | !9 = !DISubroutineType(types: !10) 8 | !10 = !{!11, !11} 9 | !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 10 | !12 = !{!13} 11 | !13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11, annotations: !14) 12 | !14 = !{!15, !16} 13 | !15 = !{!"btf_tag", !"a"} 14 | !16 = !{!"btf_tag", !"b"} 15 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-dilocalvariable.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-disubprogram.ll: -------------------------------------------------------------------------------- 1 | ;; Adapted from https://github.com/llvm/llvm-project/blob/d383df32c0d5bcdc8c160ecdd7174399aa3c5395/llvm/test/Bitcode/attr-btf_tag-disubprogram.ll 2 | 3 | !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.0 (https://github.com/llvm/llvm-project.git a6dd9d402a04d53403664bbb47771f2573c7ade0)", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) 4 | !1 = !DIFile(filename: "func.c", directory: "/home/yhs/work/tests/llvm/btf_tag") 5 | !2 = !{} 6 | !7 = !{!"clang version 13.0.0 (https://github.com/llvm/llvm-project.git a6dd9d402a04d53403664bbb47771f2573c7ade0)"} 7 | !8 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !9, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !12, annotations: !14) 8 | !9 = !DISubroutineType(types: !10) 9 | !10 = !{!11, !11} 10 | !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 11 | !12 = !{!13} 12 | !13 = !DILocalVariable(name: "a", arg: 1, scope: !8, file: !1, line: 1, type: !11) 13 | !14 = !{!15, !16} 14 | !15 = !{!"btf_tag", !"a"} 15 | !16 = !{!"btf_tag", !"b"} 16 | -------------------------------------------------------------------------------- /disasm-test/tests/btf-tag-disubprogram.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /disasm-test/tests/callbr.c: -------------------------------------------------------------------------------- 1 | // Adapted from the Clang test suite: 2 | // (https://github.com/llvm/llvm-project/blob/32103608fc073700f04238872d8b22655ddec3fb/clang/test/CodeGen/asm-goto.c#L5-L20), 3 | // which is licensed under the Apache License v2.0 4 | 5 | 6 | int main(void) { 7 | int cond = 0; 8 | asm volatile goto("testl %0, %0; jne %l1;" 9 | : /* No outputs */ 10 | : "r"(cond) 11 | : /* No clobbers */ 12 | : label_true, loop); 13 | return 0; 14 | loop: 15 | return 0; 16 | label_true: 17 | return 1; 18 | } 19 | -------------------------------------------------------------------------------- /disasm-test/tests/callbr.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'callbr.c' 2 | source_filename = "callbr.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 | ; Function Attrs: noinline nounwind optnone uwtable 7 | define dso_local i32 @main() #0 { 8 | %1 = alloca i32, align 4 9 | %2 = alloca i32, align 4 10 | store i32 0, ptr %1, align 4 11 | store i32 0, ptr %2, align 4 12 | %3 = load i32, ptr %2, align 4 13 | callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,!i,!i,~{dirflag},~{fpsr},~{flags}"(i32 %3) #1 14 | to label %4 [label %6, label %5], !srcloc !7 15 | 16 | 4: ; preds = %0 17 | store i32 0, ptr %1, align 4 18 | br label %7 19 | 20 | 5: ; preds = %0 21 | store i32 0, ptr %1, align 4 22 | br label %7 23 | 24 | 6: ; preds = %0 25 | store i32 1, ptr %1, align 4 26 | br label %7 27 | 28 | 7: ; preds = %6, %5, %4 29 | %8 = load i32, ptr %1, align 4 30 | ret i32 %8 31 | } 32 | 33 | attributes #0 = { noinline nounwind optnone uwtable "frame-pointer"="all" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } 34 | attributes #1 = { nounwind } 35 | 36 | !llvm.module.flags = !{!0, !1, !2, !3, !4} 37 | !llvm.ident = !{!5} 38 | !llvm.commandline = !{!6} 39 | 40 | !0 = !{i32 1, !"wchar_size", i32 4} 41 | !1 = !{i32 7, !"PIC Level", i32 2} 42 | !2 = !{i32 7, !"PIE Level", i32 2} 43 | !3 = !{i32 7, !"uwtable", i32 2} 44 | !4 = !{i32 7, !"frame-pointer", i32 2} 45 | !5 = !{!"clang version 15.0.6"} 46 | !6 = !{!"/home/ryanglscott/Software/clang+llvm-15.0.6/bin/clang-15 -S -emit-llvm -frecord-command-line callbr.c -o callbr.ll"} 47 | !7 = !{i64 272} 48 | -------------------------------------------------------------------------------- /disasm-test/tests/callbr.pre-llvm15.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'test.c' 2 | source_filename = "test.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-pc-linux-gnu" 5 | 6 | ; Function Attrs: noinline nounwind optnone uwtable 7 | define dso_local i32 @test1(i32 %0) #0 { 8 | %2 = alloca i32, align 4 9 | %3 = alloca i32, align 4 10 | store i32 %0, i32* %3, align 4 11 | %4 = load i32, i32* %3, align 4 12 | callbr void asm sideeffect "testl $0, $0; jne ${1:l};", "r,X,X,~{dirflag},~{fpsr},~{flags}"(i32 %4, i8* blockaddress(@test1, %7), i8* blockaddress(@test1, %6)) #1 13 | to label %5 [label %7, label %6], !srcloc !2 14 | 15 | 5: ; preds = %1 16 | store i32 0, i32* %2, align 4 17 | br label %8 18 | 19 | 6: ; preds = %1 20 | store i32 0, i32* %2, align 4 21 | br label %8 22 | 23 | 7: ; preds = %1 24 | store i32 1, i32* %2, align 4 25 | br label %8 26 | 27 | 8: ; preds = %7, %6, %5 28 | %9 = load i32, i32* %2, align 4 29 | ret i32 %9 30 | } 31 | 32 | attributes #0 = { noinline nounwind optnone uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 33 | attributes #1 = { nounwind } 34 | 35 | !llvm.module.flags = !{!0} 36 | !llvm.ident = !{!1} 37 | 38 | !0 = !{i32 1, !"wchar_size", i32 4} 39 | !1 = !{!"clang version 10.0.0-4ubuntu1 "} 40 | !2 = !{i32 265} 41 | -------------------------------------------------------------------------------- /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/tests/cmpxchg.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = '/tmp/nix-shell.mXmHgC/cmpxchg1066927-8.bc' 2 | source_filename = "disasm-test/tests/cmpxchg.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 | @val = global i32 2344, align 4, !dbg !0 7 | 8 | ; Function Attrs: noinline nounwind optnone sspstrong uwtable 9 | define i32 @do_atomic_update(i32 %0) #0 !dbg !15 { 10 | %2 = alloca i32, align 4 11 | %3 = alloca i32, align 4 12 | %4 = alloca i32, align 4 13 | %5 = alloca i8, align 1 14 | store i32 %0, i32* %2, align 4 15 | call void @llvm.dbg.declare(metadata i32* %2, metadata !18, metadata !DIExpression()), !dbg !19 16 | call void @llvm.dbg.declare(metadata i32* %3, metadata !20, metadata !DIExpression()), !dbg !21 17 | store i32 2344, i32* %3, align 4, !dbg !21 18 | %6 = load atomic i32, i32* %2 seq_cst, align 4, !dbg !22 19 | store i32 %6, i32* %4, align 4, !dbg !22 20 | %7 = load i32, i32* %3, align 4, !dbg !22 21 | %8 = load i32, i32* %4, align 4, !dbg !22 22 | %9 = cmpxchg weak i32* @val, i32 %7, i32 %8 seq_cst seq_cst, !dbg !22 23 | %10 = extractvalue { i32, i1 } %9, 0, !dbg !22 24 | %11 = extractvalue { i32, i1 } %9, 1, !dbg !22 25 | br i1 %11, label %13, label %12, !dbg !22 26 | 27 | 12: ; preds = %1 28 | store i32 %10, i32* %3, align 4, !dbg !22 29 | br label %13, !dbg !22 30 | 31 | 13: ; preds = %12, %1 32 | %14 = zext i1 %11 to i8, !dbg !22 33 | store i8 %14, i8* %5, align 1, !dbg !22 34 | %15 = load i8, i8* %5, align 1, !dbg !22 35 | %16 = trunc i8 %15 to i1, !dbg !22 36 | %17 = zext i1 %16 to i32, !dbg !22 37 | ret i32 %17, !dbg !23 38 | } 39 | 40 | ; Function Attrs: nounwind readnone speculatable willreturn 41 | declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 42 | 43 | attributes #0 = { noinline nounwind optnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="true" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 44 | attributes #1 = { nounwind readnone speculatable willreturn } 45 | 46 | !llvm.dbg.cu = !{!2} 47 | !llvm.module.flags = !{!10, !11, !12, !13} 48 | !llvm.ident = !{!14} 49 | 50 | !0 = !DIGlobalVariableExpression(var: !1, expr: !DIExpression()) 51 | !1 = distinct !DIGlobalVariable(name: "val", scope: !2, file: !3, line: 4, type: !6, isLocal: false, isDefinition: true) 52 | !2 = distinct !DICompileUnit(language: DW_LANG_C99, file: !3, producer: "clang version 11.1.0", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !4, globals: !5, splitDebugInlining: false, nameTableKind: None) 53 | !3 = !DIFile(filename: "disasm-test/tests/cmpxchg.c", directory: "/home/kquick/work/DFAMS/llvm-pretty-bc-parser") 54 | !4 = !{} 55 | !5 = !{!0} 56 | !6 = !DIDerivedType(tag: DW_TAG_typedef, name: "atomic_int", file: !7, line: 83, baseType: !8) 57 | !7 = !DIFile(filename: "/nix/store/4pk431ywfvw0k926blzwncnp699z3vh5-clang-wrapper-11.1.0/resource-root/include/stdatomic.h", directory: "") 58 | !8 = !DIDerivedType(tag: DW_TAG_atomic_type, baseType: !9) 59 | !9 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 60 | !10 = !{i32 7, !"Dwarf Version", i32 4} 61 | !11 = !{i32 2, !"Debug Info Version", i32 3} 62 | !12 = !{i32 1, !"wchar_size", i32 4} 63 | !13 = !{i32 7, !"PIC Level", i32 2} 64 | !14 = !{!"clang version 11.1.0"} 65 | !15 = distinct !DISubprogram(name: "do_atomic_update", scope: !3, file: !3, line: 6, type: !16, scopeLine: 6, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !2, retainedNodes: !4) 66 | !16 = !DISubroutineType(types: !17) 67 | !17 = !{!9, !6} 68 | !18 = !DILocalVariable(name: "newval", arg: 1, scope: !15, file: !3, line: 6, type: !6) 69 | !19 = !DILocation(line: 6, column: 33, scope: !15) 70 | !20 = !DILocalVariable(name: "old_val", scope: !15, file: !3, line: 7, type: !9) 71 | !21 = !DILocation(line: 7, column: 9, scope: !15) 72 | !22 = !DILocation(line: 8, column: 12, scope: !15) 73 | !23 = !DILocation(line: 8, column: 5, scope: !15) 74 | -------------------------------------------------------------------------------- /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/derivedtype.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'derivedtype.bc' 2 | source_filename = "derivedtype.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 | %struct.message = type { i32, i8* } 7 | 8 | ; Function Attrs: noinline nounwind optnone sspstrong uwtable 9 | define i32 @foo(%struct.message* %0) #0 !dbg !8 { 10 | %2 = alloca %struct.message*, align 8 11 | store %struct.message* %0, %struct.message** %2, align 8 12 | call void @llvm.dbg.declare(metadata %struct.message** %2, metadata !19, metadata !DIExpression()), !dbg !20 13 | %3 = load %struct.message*, %struct.message** %2, align 8, !dbg !21 14 | %4 = getelementptr inbounds %struct.message, %struct.message* %3, i32 0, i32 0, !dbg !22 15 | %5 = load i32, i32* %4, align 8, !dbg !22 16 | ret i32 %5, !dbg !23 17 | } 18 | 19 | ; Function Attrs: nounwind readnone speculatable willreturn 20 | declare void @llvm.dbg.declare(metadata, metadata, metadata) #1 21 | 22 | attributes #0 = { noinline nounwind optnone sspstrong uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "frame-pointer"="all" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="4" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "unsafe-fp-math"="false" "use-soft-float"="false" } 23 | attributes #1 = { nounwind readnone speculatable willreturn } 24 | 25 | !llvm.dbg.cu = !{!0} 26 | !llvm.module.flags = !{!3, !4, !5, !6} 27 | !llvm.ident = !{!7} 28 | 29 | !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 10.0.1 ", isOptimized: false, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) 30 | !1 = !DIFile(filename: "derivedtype.c", directory: "/home/kquick/work/RISE/llvm-regr5/disasm-test/tests") 31 | !2 = !{} 32 | !3 = !{i32 7, !"Dwarf Version", i32 4} 33 | !4 = !{i32 2, !"Debug Info Version", i32 3} 34 | !5 = !{i32 1, !"wchar_size", i32 4} 35 | !6 = !{i32 7, !"PIC Level", i32 2} 36 | !7 = !{!"clang version 10.0.1 "} 37 | !8 = distinct !DISubprogram(name: "foo", scope: !1, file: !1, line: 3, type: !9, scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: !0, retainedNodes: !2) 38 | !9 = !DISubroutineType(types: !10) 39 | !10 = !{!11, !12} 40 | !11 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 41 | !12 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !13, size: 64) 42 | !13 = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "message", file: !1, line: 1, size: 128, elements: !14) 43 | !14 = !{!15, !16} 44 | !15 = !DIDerivedType(tag: DW_TAG_member, name: "msglen", scope: !13, file: !1, line: 1, baseType: !11, size: 32) 45 | !16 = !DIDerivedType(tag: DW_TAG_member, name: "msgptr", scope: !13, file: !1, line: 1, baseType: !17, size: 64, offset: 64) 46 | !17 = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: !18, size: 64) 47 | !18 = !DIBasicType(name: "char", size: 8, encoding: DW_ATE_signed_char) 48 | !19 = !DILocalVariable(name: "mptr", arg: 1, scope: !8, file: !1, line: 3, type: !12) 49 | !20 = !DILocation(line: 3, column: 25, scope: !8) 50 | !21 = !DILocation(line: 4, column: 12, scope: !8) 51 | !22 = !DILocation(line: 4, column: 18, scope: !8) 52 | !23 = !DILocation(line: 4, column: 5, scope: !8) 53 | -------------------------------------------------------------------------------- /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/di-arg-list.ll: -------------------------------------------------------------------------------- 1 | ; ModuleID = 'di-arg-list.c' 2 | source_filename = "di-arg-list.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 | ; Function Attrs: mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn 7 | define dso_local i32 @f(i32 %0, i32 %1) local_unnamed_addr #0 !dbg !9 { 8 | call void @llvm.dbg.value(metadata i32 %0, metadata !14, metadata !DIExpression()), !dbg !17 9 | call void @llvm.dbg.value(metadata i32 %1, metadata !15, metadata !DIExpression()), !dbg !17 10 | call void @llvm.dbg.value(metadata !DIArgList(i32 %0, i32 %1), metadata !16, metadata !DIExpression(DW_OP_LLVM_arg, 0, DW_OP_LLVM_arg, 1, DW_OP_plus, DW_OP_stack_value)), !dbg !17 11 | ret i32 0, !dbg !18 12 | } 13 | 14 | ; Function Attrs: nofree nosync nounwind readnone speculatable willreturn 15 | declare void @llvm.dbg.value(metadata, metadata, metadata) #1 16 | 17 | attributes #0 = { mustprogress nofree norecurse nosync nounwind readnone uwtable willreturn "frame-pointer"="none" "min-legal-vector-width"="0" "no-trapping-math"="true" "stack-protector-buffer-size"="8" "target-cpu"="x86-64" "target-features"="+cx8,+fxsr,+mmx,+sse,+sse2,+x87" "tune-cpu"="generic" } 18 | attributes #1 = { nofree nosync nounwind readnone speculatable willreturn } 19 | 20 | !llvm.dbg.cu = !{!0} 21 | !llvm.module.flags = !{!3, !4, !5, !6} 22 | !llvm.ident = !{!7} 23 | !llvm.commandline = !{!8} 24 | 25 | !0 = distinct !DICompileUnit(language: DW_LANG_C99, file: !1, producer: "clang version 13.0.1", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, enums: !2, splitDebugInlining: false, nameTableKind: None) 26 | !1 = !DIFile(filename: "di-arg-list.c", directory: "/home/rscott/Documents/Hacking/Haskell/llvm-pretty-bc-parser/disasm-test/tests") 27 | !2 = !{} 28 | !3 = !{i32 7, !"Dwarf Version", i32 4} 29 | !4 = !{i32 2, !"Debug Info Version", i32 3} 30 | !5 = !{i32 1, !"wchar_size", i32 4} 31 | !6 = !{i32 7, !"uwtable", i32 1} 32 | !7 = !{!"clang version 13.0.1"} 33 | !8 = !{!"/home/rscott/Software/clang+llvm-13.0.1/bin/clang-13 -S -emit-llvm -g -O1 -frecord-command-line di-arg-list.c -o di-arg-list.at-least-llvm13.ll"} 34 | !9 = distinct !DISubprogram(name: "f", scope: !1, file: !1, line: 1, type: !10, scopeLine: 1, flags: DIFlagPrototyped | DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !0, retainedNodes: !13) 35 | !10 = !DISubroutineType(types: !11) 36 | !11 = !{!12, !12, !12} 37 | !12 = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed) 38 | !13 = !{!14, !15, !16} 39 | !14 = !DILocalVariable(name: "x", arg: 1, scope: !9, file: !1, line: 1, type: !12) 40 | !15 = !DILocalVariable(name: "y", arg: 2, scope: !9, file: !1, line: 1, type: !12) 41 | !16 = !DILocalVariable(name: "z", scope: !9, file: !1, line: 2, type: !12) 42 | !17 = !DILocation(line: 0, scope: !9) 43 | !18 = !DILocation(line: 3, column: 3, scope: !9) 44 | -------------------------------------------------------------------------------- /disasm-test/tests/di-arg-list.pre-llvm13.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /disasm-test/tests/dilocalvariable.ll: -------------------------------------------------------------------------------- 1 | ;; Adapted from https://github.com/llvm/llvm-project/blob/2ede126b1b3fae52cddece5cf1f75b474a9c7932/llvm/test/Assembler/dilocalvariable.ll 2 | 3 | ; CHECK: !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9} 4 | !named = !{!0, !1, !2, !3, !4, !5, !6, !7, !8, !9} 5 | 6 | !llvm.module.flags = !{!10} 7 | !llvm.dbg.cu = !{!1} 8 | 9 | !0 = distinct !DISubprogram(unit: !1) 10 | !1 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang", 11 | file: !2, 12 | isOptimized: true, flags: "-O2", 13 | splitDebugFilename: "abc.debug", emissionKind: 2) 14 | !2 = !DIFile(filename: "path/to/file", directory: "/path/to/dir") 15 | !3 = !DIBasicType(name: "int", size: 32, align: 32, encoding: DW_ATE_signed) 16 | !4 = !DILocation(scope: !0) 17 | 18 | ; CHECK: !5 = !DILocalVariable(name: "foo", arg: 3, scope: !0, file: !2, line: 7, type: !3, flags: DIFlagArtificial, align: 32) 19 | ; CHECK: !6 = !DILocalVariable(name: "foo", scope: !0, file: !2, line: 7, type: !3, flags: DIFlagArtificial) 20 | !5 = !DILocalVariable(name: "foo", arg: 3, 21 | scope: !0, file: !2, line: 7, type: !3, 22 | flags: DIFlagArtificial, align: 32) 23 | !6 = !DILocalVariable(name: "foo", scope: !0, 24 | file: !2, line: 7, type: !3, flags: DIFlagArtificial) 25 | 26 | ; CHECK: !7 = !DILocalVariable(arg: 1, scope: !0) 27 | ; CHECK: !8 = !DILocalVariable(scope: !0) 28 | !7 = !DILocalVariable(scope: !0, arg: 1) 29 | !8 = !DILocalVariable(scope: !0) 30 | !9 = distinct !{} 31 | 32 | !10 = !{i32 2, !"Debug Info Version", i32 3} 33 | -------------------------------------------------------------------------------- /disasm-test/tests/dilocalvariable.pre-llvm14.ll: -------------------------------------------------------------------------------- 1 | SKIP_TEST 2 | -------------------------------------------------------------------------------- /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 | ;