{"id":37649581,"url":"https://github.com/rayanht/spirvsmith","last_synced_at":"2026-01-16T11:30:56.250Z","repository":{"id":41882179,"uuid":"429076310","full_name":"rayanht/SPIRVSmith","owner":"rayanht","description":"A differential testing tool targeting SPIRV based on structured fuzzing techniques","archived":false,"fork":false,"pushed_at":"2022-12-09T06:38:04.000Z","size":815,"stargazers_count":15,"open_issues_count":5,"forks_count":2,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-10T22:52:38.555Z","etag":null,"topics":["differential-testing","fuzzing","moltenvk","spirv","spirv-cross","spirv-tools","swiftshader","vulkan"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/rayanht.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2021-11-17T14:23:12.000Z","updated_at":"2024-10-17T10:00:48.000Z","dependencies_parsed_at":"2023-01-25T17:01:36.246Z","dependency_job_id":null,"html_url":"https://github.com/rayanht/SPIRVSmith","commit_stats":null,"previous_names":[],"tags_count":12,"template":false,"template_full_name":null,"purl":"pkg:github/rayanht/SPIRVSmith","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayanht%2FSPIRVSmith","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayanht%2FSPIRVSmith/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayanht%2FSPIRVSmith/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayanht%2FSPIRVSmith/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rayanht","download_url":"https://codeload.github.com/rayanht/SPIRVSmith/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rayanht%2FSPIRVSmith/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28478290,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T06:30:42.265Z","status":"ssl_error","status_checked_at":"2026-01-16T06:30:16.248Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["differential-testing","fuzzing","moltenvk","spirv","spirv-cross","spirv-tools","swiftshader","vulkan"],"created_at":"2026-01-16T11:30:56.145Z","updated_at":"2026-01-16T11:30:56.244Z","avatar_url":"https://github.com/rayanht.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# SPIRVSmith\n\n![GitHub Workflow Status](https://img.shields.io/github/workflow/status/rayanht/SPIRVSmith/Build,%20Test%20and%20Deploy)\n![GitHub](https://img.shields.io/github/license/rayanht/SPIRVSmith)\n[![Test Coverage](https://api.codeclimate.com/v1/badges/5f91595e621ebb1f1da2/test_coverage)](https://codeclimate.com/github/rayanht/SPIRVSmith/test_coverage)\n[![Maintainability](https://api.codeclimate.com/v1/badges/5f91595e621ebb1f1da2/maintainability)](https://codeclimate.com/github/rayanht/SPIRVSmith/maintainability)\n[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B22322%2Fgithub.com%2Frayanht%2FSPIRVSmith.svg?type=shield)](https://app.fossa.com/projects/custom%2B22322%2Fgithub.com%2Frayanht%2FSPIRVSmith?ref=badge_shield)\n[![Code style: black](https://img.shields.io/badge/code%20style-black-000000.svg)](https://github.com/psf/black)\n[![DOI](https://zenodo.org/badge/429076310.svg)](https://zenodo.org/badge/latestdoi/429076310)\n\n## SPIRVSmith\n\nSPIRVSmith is a differential testing tool that leverages structured fuzzing techniques to find bugs in producers and consumers of SPIRV shaders.\n\nSPIRVSmith attempts to find bugs in the following projects:\n- [SPIRV-Tools](https://github.com/KhronosGroup/SPIRV-Tools) - mostly the validator and reducer components.\n- [SPIRV-Cross](https://github.com/KhronosGroup/SPIRV-Cross)\n- [Amber](https://github.com/google/amber)\n- [SwiftShader](https://github.com/google/swiftshader)\n- [MoltenVK](https://github.com/KhronosGroup/MoltenVK)\n- ...and more to come!\n\n## Table of Contents\n- [Installation](#installation)\n- [Usage](#usage)\n- [How does it work?](#how-does-it-work)\n  - [Differential testing](#differential-testing)\n  - [Program Reconditioning](#program-reconditioning)\n- [SPIR-V Language Coverage](#spirv-language-coverage)\n- [Contributing](#contributing)\n- [Authors](#authors)\n- [License](#license)\n\n\n## Installation\n\nSPIRVSmith uses `poetry` to manage Python dependencies and ships with scripts to install external dependencies.\n\n1. Follow the poetry [installation instructions](https://python-poetry.org/docs/#installation) for your platform.\n\n1. Grab a local copy of SPIRVSmith:\n\n```bash\n$ git clone https://github.com/rayanht/SPIRVSmith.git \u0026\u0026 cd SPIRVSmith\n```\n\n3. Install Python dependencies using `poetry` and start a `poetry` shell:\n\n```bash\n$ poetry install \u0026\u0026 poetry shell\n```\n\n4. Install the external dependencies:\n\n```bash\n$ mkdir bin\n$ sh scripts/get_spirv_tools.sh \u003cplatform\u003e\n```\n\nReplace `\u003cplatform\u003e` by either `linux` or `macos` (No support for Windows :sob:)\n\n\n## Usage\n\nThe first step is to run `SPIRVSmith` is to head to `config.py`. That file contains the various parameters that are used to dictate the behaviour of the fuzzer.\n\n`SPIRVSmith` is highly parametrizable, you can choose to disable certain features of the SPIR-V language (e.g. do not emit any control flow operation), limit the number of global constants generated, favour the generation of certain kinds of instructions etc.\n\nOnce you are happy with your parametrization, make sure you are in a `poetry` virtual environment (`$ poetry shell`) and run `SPIRVSmith`:\n\n```bash\n$ sh scripts/run.sh\n```\n\nSPIR-V assembly files will be saved as they are generated to the `out/` directory and the fuzzer can be stopped at any time by pressing `Ctrl+C`.\n\n## How does it work?\n\n### Differential Testing\nThe bread and butter of `SPIRVSmith` is **differential testing** (sometimes called differential fuzzing), in which we provide the same SPIRV shader to similar consumers (say three different SPIRV compilers for example), execute the three resulting programs and compare the values contained inside all buffers at the end of exeuction.\n\nIn a **fully deterministic** program `(== synchronous \u0026\u0026 free of undefined behaviour)`, we expect all these buffers to be exactly the same at the end of execution, regardless of what compiler was used to generate said program. If one program ends up with different buffers than the other two, we have a strong reason to believe that the compiler that generated it has a **bug**.\n\nThis concept can be extended further by varying the platform that executes the shader. If we get different results by running the same shader on an Nvidia GPU, an AMD GPU, and an Intel integrated graphics chip then there is a good chance that either the underlying Vulkan engine or the GPU driver has a **bug** (possibly both).\n\nThe constraint on determinism creates an interesting problem, how can we ensure that the **randomly** generated programs are free of undefined behaviour? Unlike existing differential testing tools, `SPIRVSmith` does not perform any static analysis or backtracking at generation-time to enforce this constraint, we rather implement the idea of **program reconditioning** by **Donaldson et al.**\n\n### Program Reconditioning\n\n**Donaldson et al.** introduce the idea of program reconditioning as \"a method for leveraging off-the-shelf test case reducers to simplify programs that expose miscompilation bugs during randomised differential testing\".\n\nThis approach solves the issues raised by **Yang et al.** in the case of [CSmith](https://github.com/csmith-project/csmith) where test case reducers couldn't be used to provide concise, actionable bug reports since they would themselves often introduce undefined behaviour.\n\nProgram reconditioning works by decoupling the process of generating a program and the process of ensuring that said program is free of undefined behaviour. This is in contrast to **Livinskii et al.** in [YARPGen](https://github.com/intel/yarpgen) where code generation steps and static analysis steps are interleaved.\n\n**Donaldson et al.** describe a **rule-based reconditioning approach** where transforms are applied to constructs that **could** exhibit undefined behaviour. Transforms are applied to all eligible construct in a blanket manner, **no** static analysis is performed to determine which constructs are in fact worth reconditioning. Here is example of reconditioning a **GLSL** shader:\n\n#### Original\n```glsl\nfloat A [3]; // Not initialised\nvoid main () {\n    int i = int (A[0]);\n    float f = 2000000.0;\n    while (i != -42) { // Might not terminate\n        A[i] = f; // Out of  bounds ?\n        f = f + f; // Roundoff\n        int j = i ++ + ( i / ( i - 1)); // Order of side effects, divide by zero?\n        i = j;\n    }\n}\n```\n\n#### Reconditioned\n```glsl\n// [ Declarations of SAFE_ABS , MAKE_IN_RANGE and SAFE_DIV ]\nuint _loop_count = 0u;\nconst uint _loop_limit = 100u;\nfloat A [3] = float [3](1.0 , 1.0 , 1.0);\nvoid main () {\n    int i = int (A[0]);\n    float f = 2000000.0;\n    while (i != -42) {\n        if (_loop_count \u003e= _loop_limit) break;\n        _loop_count ++;\n        A[SAFE_ABS(i) % 3] = f ;\n        f = MAKE_IN_RANGE(f + f);\n        int _t = SAFE_DIV(i , i - 1);\n        int j = i ++ + _t;\n        i = j;\n    }\n}\n```\n\n## SPIRV Language Coverage\n\n\u003cdetails\u003e\n\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n### Instructions\n\n\n#### Miscellanous\n\n\u003cdetails\u003e\n\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpNop | :red_circle: |\n| OpUndef | :red_circle: |\n| OpSizeOf | :red_circle: |\n\n\u003c/details\u003e\n\n#### Debug\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpSourceContinued | :red_circle: |\n| OpSource | :red_circle: |\n| OpSourceExtension | :red_circle: |\n| OpName | :red_circle: |\n| OpMemberName | :red_circle: |\n| OpString | :red_circle: |\n| OpLine | :red_circle: |\n| OpNoLine | :red_circle: |\n| OpModuleProcessed | :red_circle: |\n\n\u003c/details\u003e\n\n#### Annotation\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpDecorate | :white_check_mark: |\n| OpMemberDecorate | :white_check_mark: |\n| OpDecorationGroup | :red_circle: |\n| OpGroupDecorate | :red_circle: |\n| OpGroupMemberDecorate | :red_circle: |\n| OpDecorateId | :red_circle: |\n| OpDecorateString | :red_circle: |\n| OpMemberDecorateString | :red_circle: |\n\n\u003c/details\u003e\n\n#### Extension\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpExtension | :white_check_mark: |\n| OpExtInstImport | :white_check_mark: |\n| OpExtInst | :white_check_mark: |\n\n\u003c/details\u003e\n\n#### Mode-Setting\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpMemoryModel | :white_check_mark: |\n| OpEntryPoint | :white_check_mark: |\n| OpExecutionMode | :white_check_mark: |\n| OpCapability | :white_check_mark: |\n| OpExecutionModeId | :red_circle: |\n\n\u003c/details\u003e\n\n#### Type-Declaration\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpTypeVoid | :white_check_mark: |\n| OpTypeBool | :white_check_mark: |\n| OpTypeInt | :white_check_mark: |\n| OpTypeFloat | :white_check_mark: |\n| OpTypeVector | :white_check_mark: |\n| OpTypeMatrix | :white_check_mark: |\n| OpTypeImage | :red_circle: |\n| OpTypeSampler | :red_circle: |\n| OpTypeSampledImage | :red_circle: |\n| OpTypeArray | :white_check_mark: |\n| OpTypeRuntimeArray | :red_circle: |\n| OpTypeStruct | :white_check_mark: |\n| OpTypeOpaque | :red_circle: |\n| OpTypePointer | :white_check_mark: |\n| OpTypeFunction | :white_check_mark: |\n\n\u003c/details\u003e\n\n#### Constant-Creation\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpConstantTrue | :white_check_mark: |\n| OpConstantFalse | :white_check_mark: |\n| OpConstant | :white_check_mark: |\n| OpConstantComposite | :white_check_mark: |\n| OpConstantSampler | :red_circle: |\n| OpConstantNull | :red_circle: |\n| OpSpecConstantTrue | :red_circle: |\n| OpSpecConstantFalse | :red_circle: |\n| OpSpecConstant | :red_circle: |\n| OpSpecConstantComposite | :red_circle: |\n| OpSpecConstantOp | :red_circle: |\n\n\u003c/details\u003e\n\n#### Memory\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpVariable | :white_check_mark: |\n| OpImageTexelPointer | :red_circle: |\n| OpLoad | :white_check_mark: |\n| OpStore |:white_check_mark:  |\n| OpCopyMemory | :red_circle: |\n| OpCopyMemorySized | :red_circle: |\n| OpAccessChain | :white_check_mark: |\n| OpInBoundsAccessChain | :red_circle: |\n| OpPtrAccessChain | :red_circle: |\n| OpPtrEqual | :red_circle: |\n| OpPtrNotEqual | :red_circle: |\n| OpPtrDiff | :red_circle: |\n\n\u003c/details\u003e\n\n#### Function\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpFunction | :white_check_mark: |\n| OpFunctionParameter | :white_check_mark: |\n| OpFunctionEnd | :white_check_mark: |\n| OpFunctionCall | :red_circle: |\n\n\u003c/details\u003e\n\n#### Image\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpSampledImage | :red_circle: |\n| OpImageSampleImplicitLod | :red_circle: |\n| OpImageSampleExplicitLod | :red_circle: |\n| OpImageSampleDrefImplicitLod |:red_circle:  |\n| OpImageSampleDrefExplicitLod | :red_circle: |\n| OpImageSampleProjImplicitLod | :red_circle: |\n| OpImageSampleProjExplicitLod | :red_circle: |\n| OpImageSampleProjDrefImplicitLod | :red_circle: |\n| OpImageSampleProjDrefExplicitLod | :red_circle: |\n| OpImageFetch | :red_circle: |\n| OpImageGather | :red_circle: |\n| OpImageDrefGather | :red_circle: |\n| OpImageRead | :red_circle: |\n| OpImageWrite | :red_circle: |\n| OpImage | :red_circle: |\n| OpImageQueryFormat | :red_circle: |\n| OpImageQueryOrder | :red_circle: |\n| OpImageQuerySizeLod | :red_circle: |\n| OpImageQuerySize | :red_circle: |\n| OpImageQueryLod | :red_circle: |\n| OpImageQueryLevels | :red_circle: |\n| OpImageQuerySamples | :red_circle: |\n| OpImageSparseSampleImplicitLod | :red_circle: |\n| OpImageSparseSampleExplicitLod | :red_circle: |\n| OpImageSparseSampleDrefImplicitLod | :red_circle: |\n| OpImageSparseSampleDrefExplicitLod | :red_circle: |\n| OpImageSparseFetch | :red_circle: |\n| OpImageSparseGather | :red_circle: |\n| OpImageSparseDrefGather | :red_circle: |\n| OpImageSparseTexelsResident | :red_circle: |\n| OpImageSparseRead | :red_circle: |\n\n\u003c/details\u003e\n\n#### Conversion\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpConvertFToU | :white_check_mark: |\n| OpConvertFToS | :white_check_mark: |\n| OpConvertSToF | :white_check_mark: |\n| OpConvertUToF | :white_check_mark:  |\n| OpUConvert | :red_circle: |\n| OpSConvert | :red_circle: |\n| OpFConvert | :red_circle: |\n| OpQuantizeToF16 | :red_circle: |\n| OpConvertPtrToU | :red_circle: |\n| OpSatConvertSToU | :red_circle: |\n| OpSatConvertUToS | :red_circle: |\n| OpConvertUToPtr | :red_circle: |\n| OpPtrCastToGeneric | :red_circle: |\n| OpGenericCastToPtr | :red_circle: |\n| OpGenericCastToPtrExplicit | :red_circle: |\n| OpBitcast | :red_circle: |\n\n\u003c/details\u003e\n\n#### Composite\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpVectorExtractDynamic | :white_check_mark: |\n| OpVectorInsertDynamic | :white_check_mark: |\n| OpVectorShuffle | :white_check_mark: |\n| OpCompositeConstruct | :red_circle:  |\n| OpCompositeExtract | :white_check_mark: |\n| OpCompositeInsert | :white_check_mark: |\n| OpCopyObject | :white_check_mark: |\n| OpTranspose | :white_check_mark: |\n| OpCopyLogical | :red_circle: |\n\n\u003c/details\u003e\n\n#### Arithmetic\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpSNegate | :white_check_mark: |\n| OpFNegate | :white_check_mark: |\n| OpIAdd | :white_check_mark: |\n| OpFAdd | :white_check_mark:  |\n| OpISub | :white_check_mark: |\n| OpFSub | :white_check_mark: |\n| OpIMul | :white_check_mark: |\n| OpFMul | :white_check_mark: |\n| OpUDiv | :white_check_mark: |\n| OpSDiv | :white_check_mark: |\n| OpFDiv | :white_check_mark: |\n| OpUMod | :white_check_mark: |\n| OpSRem | :white_check_mark: |\n| OpSMod | :white_check_mark: |\n| OpFRem | :white_check_mark: |\n| OpFMod | :white_check_mark: |\n| OpVectorTimesScalar | :white_check_mark: |\n| OpMatrixTimesScalar | :white_check_mark: |\n| OpVectorTimesMatrix | :white_check_mark: |\n| OpMatrixTimesVector | :white_check_mark: |\n| OpMatrixTimesMatrix | :white_check_mark: |\n| OpOuterProduct | :white_check_mark: |\n| OpDot | :white_check_mark: |\n| OpIAddCarry | :red_circle: |\n| OpISubBorrow | :red_circle: |\n| OpUMulExtended | :red_circle: |\n| OpSMulExtended | :red_circle: |\n\n\u003c/details\u003e\n\n#### Bit\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpShiftRightLogical | :white_check_mark: |\n| OpShiftRightArithmetic | :white_check_mark: |\n| OpShiftLeftLogical | :white_check_mark: |\n| OpBitwiseOr |:white_check_mark:  |\n| OpBitwiseXor | :white_check_mark: |\n| OpBitwiseAnd | :white_check_mark: |\n| OpNot | :white_check_mark: |\n| OpBitFieldInsert | :white_check_mark: |\n| OpBitFieldSExtract | :white_check_mark: |\n| OpBitFieldUExtract | :white_check_mark: |\n| OpBitReverse | :white_check_mark: |\n| OpBitCount | :white_check_mark: |\n\n\u003c/details\u003e\n\n#### Relational and Logical\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpAny | :white_check_mark: |\n| OpAll | :white_check_mark: |\n| OpIsNan | :white_check_mark: |\n| OpIsInf |:white_check_mark:  |\n| OpIsFinite | :red_circle: |\n| OpIsNormal | :red_circle: |\n| OpSignBitSet | :red_circle: |\n| OpOrdered | :red_circle: |\n| OpUnordered | :red_circle: |\n| OpLogicalEqual | :white_check_mark: |\n| OpLogicalNotEqual | :white_check_mark: |\n| OpLogicalOr | :white_check_mark: |\n| OpLogicalAnd | :white_check_mark: |\n| OpLogicalNot | :white_check_mark: |\n| OpSelect |:white_check_mark:  |\n| OpIEqual | :white_check_mark: |\n| OpINotEqual | :white_check_mark: |\n| OpUGreaterThan | :white_check_mark: |\n| OpSGreaterThan | :white_check_mark: |\n| OpUGreaterThanEqual | :white_check_mark: |\n| OpSGreaterThanEqual | :white_check_mark: |\n| OpULessThan | :white_check_mark: |\n| OpSLessThan | :white_check_mark: |\n| OpULessThanEqual | :white_check_mark: |\n| OpSLessThanEqual | :white_check_mark: |\n| OpFOrdEqual | :white_check_mark: |\n| OpFUnordEqual | :white_check_mark: |\n| OpFOrdNotEqual | :white_check_mark: |\n| OpFUnordNotEqual | :white_check_mark: |\n| OpFOrdLessThan | :white_check_mark: |\n| OpFUnordLessThan | :white_check_mark: |\n| OpFOrdGreaterThan | :white_check_mark: |\n| OpFUnordGreaterThan | :white_check_mark: |\n| OpFOrdLessThanEqual | :white_check_mark: |\n| OpFUnordLessThanEqual | :white_check_mark: |\n| OpFOrdGreaterThanEqual | :white_check_mark: |\n| OpFUnordGreaterThanEqual | :white_check_mark: |\n\n\u003c/details\u003e\n\n#### Control Flow\n\n\u003cdetails\u003e\n\n\u003csummary\u003eExpand\u003c/summary\u003e\n\n\n|OpCode| Status |\n|--|--|\n| OpPhi | :red_circle: |\n| OpLoopMerge | :white_check_mark: |\n| OpSelectionMerge | :white_check_mark: |\n| OpLabel |:white_check_mark:  |\n| OpBranch | :white_check_mark: |\n| OpBranchConditional | :white_check_mark: |\n| OpSwitch | :red_circle: |\n| OpReturn | :red_circle: |\n| OpReturnValue | :red_circle: |\n\n\u003c/details\u003e\n\n\u003c/details\u003e\n\n## Contributing\n\nEncountered a bug? Have an idea for a new feature? This project is open to all\nsorts of contribution! Feel free to head to the `Issues` tab and describe your\nrequest!\n\n## Authors\n\n* **Rayan Hatout** - [GitHub](https://github.com/rayanht)\n  | [Twitter](https://twitter.com/rayanhtt)\n  | [LinkedIn](https://www.linkedin.com/in/rayan-hatout/)\n\n## License\nThis project is licensed under the Apache 2.0 license.\n\n[![FOSSA Status](https://app.fossa.com/api/projects/custom%2B22322%2Fgithub.com%2Frayanht%2FSPIRVSmith.svg?type=large)](https://app.fossa.com/projects/custom%2B22322%2Fgithub.com%2Frayanht%2FSPIRVSmith?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frayanht%2Fspirvsmith","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frayanht%2Fspirvsmith","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frayanht%2Fspirvsmith/lists"}