diff --git a/llvm/lib/Target/EVM/CMakeLists.txt b/llvm/lib/Target/EVM/CMakeLists.txt index 179ead9401eb..8bb7ea6b08cf 100644 --- a/llvm/lib/Target/EVM/CMakeLists.txt +++ b/llvm/lib/Target/EVM/CMakeLists.txt @@ -37,18 +37,18 @@ add_llvm_target(EVMCodeGen EVMMachineFunctionInfo.cpp EVMMarkRecursiveFunctions.cpp EVMMCInstLower.cpp - EVMMachineFunctionInfo.cpp EVMOptimizeLiveIntervals.cpp + EVMPeephole.cpp EVMRegColoring.cpp EVMRegisterInfo.cpp EVMSHA3ConstFolding.cpp EVMSingleUseExpression.cpp EVMSplitCriticalEdges.cpp - EVMStackModel.cpp - EVMStackShuffler.cpp EVMStackSolver.cpp + EVMStackModel.cpp EVMStackify.cpp EVMStackifyCodeEmitter.cpp + EVMStackShuffler.cpp EVMSubtarget.cpp EVMTargetMachine.cpp EVMTargetTransformInfo.cpp @@ -71,6 +71,8 @@ add_llvm_target(EVMCodeGen Target TargetParser TransformUtils + EVMDesc + EVMInfo ADD_TO_COMPONENT EVM diff --git a/llvm/lib/Target/EVM/EVM.h b/llvm/lib/Target/EVM/EVM.h index 3589454f1011..34b0f9de974e 100644 --- a/llvm/lib/Target/EVM/EVM.h +++ b/llvm/lib/Target/EVM/EVM.h @@ -68,6 +68,7 @@ FunctionPass *createEVMSplitCriticalEdges(); FunctionPass *createEVMStackify(); FunctionPass *createEVMBPStackification(); FunctionPass *createEVMLowerJumpUnless(); +FunctionPass *createEVMPeepholePass(); ModulePass *createEVMFinalizeStackFrames(); ModulePass *createEVMMarkRecursiveFunctionsPass(); ModulePass *createEVMConstantUnfolding(); @@ -91,6 +92,7 @@ void initializeEVMLowerJumpUnlessPass(PassRegistry &); void initializeEVMFinalizeStackFramesPass(PassRegistry &); void initializeEVMMarkRecursiveFunctionsPass(PassRegistry &); void initializeEVMConstantUnfoldingPass(PassRegistry &); +void initializeEVMPeepholePass(PassRegistry &); struct EVMLinkRuntimePass : PassInfoMixin { EVMLinkRuntimePass() = default; diff --git a/llvm/lib/Target/EVM/EVMLowerJumpUnless.cpp b/llvm/lib/Target/EVM/EVMLowerJumpUnless.cpp index 938c095db557..a553529c7c1f 100644 --- a/llvm/lib/Target/EVM/EVMLowerJumpUnless.cpp +++ b/llvm/lib/Target/EVM/EVMLowerJumpUnless.cpp @@ -14,20 +14,14 @@ #include "EVMMachineFunctionInfo.h" #include "EVMSubtarget.h" #include "MCTargetDesc/EVMMCTargetDesc.h" -#include "llvm/ADT/Statistic.h" #include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineInstrBuilder.h" -#include "llvm/Support/CodeGen.h" -#include "llvm/Target/TargetMachine.h" -#include "llvm/Target/TargetOptions.h" using namespace llvm; #define DEBUG_TYPE "evm-lower-jump-unless" #define EVM_LOWER_JUMP_UNLESS_NAME "EVM Lower jump_unless" -STATISTIC(NumPseudoJumpUnlessFolded, "Number of PseudoJUMP_UNLESS folded"); - namespace { class EVMLowerJumpUnless final : public MachineFunctionPass { public: @@ -57,66 +51,14 @@ FunctionPass *llvm::createEVMLowerJumpUnless() { return new EVMLowerJumpUnless(); } -// Lower jump_unless into iszero and jumpi instructions. This instruction -// can only be present in non-stackified functions. -static void lowerJumpUnless(MachineInstr &MI, const EVMInstrInfo *TII, - const bool IsStackified, MachineRegisterInfo &MRI) { - assert(!IsStackified && "Found jump_unless in stackified function"); - assert(MI.getNumExplicitOperands() == 2 && - "Unexpected number of operands in jump_unless"); - auto NewReg = MRI.createVirtualRegister(&EVM::GPRRegClass); - BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(EVM::ISZERO), NewReg) - .add(MI.getOperand(1)); - BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(EVM::JUMPI)) - .add(MI.getOperand(0)) - .addReg(NewReg); -} - -/// Fold ` ; PseudoJUMP_UNLESS` into `PseudoJUMPI`. -/// -/// Supported `PrevMI` patterns and changes: -/// • `ISZERO_S` -> delete `ISZERO_S` -/// • `EQ_S` -> change to `SUB_S` -/// • `SUB_S` -> change to `EQ_S` -/// -/// Returns `true` if any fold was performed. -static bool tryFoldJumpUnless(MachineInstr &MI, const EVMInstrInfo *TII) { - auto I = MachineBasicBlock::iterator(&MI); - auto *PrevMI = I == MI.getParent()->begin() ? nullptr : &*std::prev(I); - bool CanFold = PrevMI && (PrevMI->getOpcode() == EVM::ISZERO_S || - PrevMI->getOpcode() == EVM::EQ_S || - PrevMI->getOpcode() == EVM::SUB_S); - - if (!CanFold) - return false; - - ++NumPseudoJumpUnlessFolded; - - if (PrevMI->getOpcode() == EVM::ISZERO_S) - PrevMI->eraseFromParent(); - else if (PrevMI->getOpcode() == EVM::EQ_S) - PrevMI->setDesc(TII->get(EVM::SUB_S)); - else if (PrevMI->getOpcode() == EVM::SUB_S) - PrevMI->setDesc(TII->get(EVM::EQ_S)); - return true; -} - -/// Lower a `PseudoJUMP_UNLESS` to condition-setting + `PseudoJUMPI`. -/// -/// If `FoldJumps` is enabled and the local pattern allows it, an -/// optimisation in `tryFoldJumpUnless` removes the explicit `ISZERO_S`. -/// Otherwise the pseudo-op expands to: -/// ISZERO_S -/// PseudoJUMPI +// Lower pseudo jump_unless into iszero and jumpi instructions. This pseudo +// instruction can only be present in stackified functions. static void lowerPseudoJumpUnless(MachineInstr &MI, const EVMInstrInfo *TII, - const bool IsStackified, - const bool FoldJumps) { + const bool IsStackified) { assert(IsStackified && "Found pseudo jump_unless in non-stackified function"); assert(MI.getNumExplicitOperands() == 1 && "Unexpected number of operands in pseudo jump_unless"); - - if (!FoldJumps || !tryFoldJumpUnless(MI, TII)) - BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(EVM::ISZERO_S)); + BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(EVM::ISZERO_S)); BuildMI(*MI.getParent(), MI, MI.getDebugLoc(), TII->get(EVM::PseudoJUMPI)) .add(MI.getOperand(0)); } @@ -127,32 +69,20 @@ bool EVMLowerJumpUnless::runOnMachineFunction(MachineFunction &MF) { << "********** Function: " << MF.getName() << '\n'; }); - CodeGenOptLevel OptLevel = MF.getTarget().getOptLevel(); - MachineRegisterInfo &MRI = MF.getRegInfo(); const auto *TII = MF.getSubtarget().getInstrInfo(); const bool IsStackified = MF.getInfo()->getIsStackified(); bool Changed = false; for (MachineBasicBlock &MBB : MF) { - auto TermIt = MBB.getFirstInstrTerminator(); - if (TermIt == MBB.end()) - continue; - - switch (TermIt->getOpcode()) { - case EVM::PseudoJUMP_UNLESS: - lowerPseudoJumpUnless(*TermIt, TII, IsStackified, - OptLevel != CodeGenOptLevel::None); - break; - case EVM::JUMP_UNLESS: - lowerJumpUnless(*TermIt, TII, IsStackified, MRI); - break; - default: - continue; - } + for (auto &MI : make_early_inc_range(MBB)) { + if (MI.getOpcode() != EVM::PseudoJUMP_UNLESS) + continue; - TermIt->eraseFromParent(); - Changed = true; + lowerPseudoJumpUnless(MI, TII, IsStackified); + MI.eraseFromParent(); + Changed = true; + } } return Changed; } diff --git a/llvm/lib/Target/EVM/EVMPeephole.cpp b/llvm/lib/Target/EVM/EVMPeephole.cpp new file mode 100644 index 000000000000..93cc7a4a80d7 --- /dev/null +++ b/llvm/lib/Target/EVM/EVMPeephole.cpp @@ -0,0 +1,100 @@ + +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Pre-emission peephole optimizations. +// +//===----------------------------------------------------------------------===// + +#include "EVM.h" +#include "MCTargetDesc/EVMMCTargetDesc.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/CodeGen/MachineFunctionPass.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineInstrBuilder.h" +#include "llvm/CodeGen/TargetInstrInfo.h" +#include "llvm/CodeGen/TargetSubtargetInfo.h" + +#define DEBUG_TYPE "evm-peephole" +#define EVM_PEEPHOLE "EVM Peephole" + +using namespace llvm; + +namespace { +/// Perform foldings on stack-form MIR before emission. +class EVMPeephole final : public MachineFunctionPass { +public: + static char ID; + EVMPeephole() : MachineFunctionPass(ID) {} + + StringRef getPassName() const override { return EVM_PEEPHOLE; } + bool runOnMachineFunction(MachineFunction &MF) override; + bool optimizeConditionaJumps(MachineBasicBlock &MBB) const; +}; +} // namespace + +bool EVMPeephole::runOnMachineFunction(MachineFunction &MF) { + bool Changed = false; + for (MachineBasicBlock &MBB : MF) { + Changed |= optimizeConditionaJumps(MBB); + } + return Changed; +} + +static bool isNegatedAndJumpedOn(const MachineBasicBlock &MBB, + MachineBasicBlock::const_iterator I) { + if (I == MBB.end() || I->getOpcode() != EVM::ISZERO_S) + return false; + ++I; + // When a conditional jump’s predicate is a (possibly nested) bitwise `or`, + // both operands are eligible for folding. Currently we only fold the operand + // computed last. + // TODO: #887 Apply folding to all operands. + while (I != MBB.end() && I->getOpcode() == EVM::OR_S) + ++I; + return I != MBB.end() && I->getOpcode() == EVM::PseudoJUMPI; +} + +bool EVMPeephole::optimizeConditionaJumps(MachineBasicBlock &MBB) const { + MachineBasicBlock::iterator I = MBB.begin(); + const TargetInstrInfo *TII = MBB.getParent()->getSubtarget().getInstrInfo(); + + while (I != MBB.end()) { + // Fold ISZERO ISZERO to nothing, only if it's a predicate to JUMPI. + if (I->getOpcode() == EVM::ISZERO_S && + isNegatedAndJumpedOn(MBB, std::next(I))) { + std::next(I)->eraseFromParent(); + I->eraseFromParent(); + return true; + } + + // Fold EQ ISZERO to SUB, only if it's a predicate to JUMPI. + if (I->getOpcode() == EVM::EQ_S && + isNegatedAndJumpedOn(MBB, std::next(I))) { + I->setDesc(TII->get(EVM::SUB_S)); + std::next(I)->eraseFromParent(); + return true; + } + + // Fold SUB ISZERO to EQ, only if it's a predicate to JUMPI. + if (I->getOpcode() == EVM::SUB_S && + isNegatedAndJumpedOn(MBB, std::next(I))) { + I->setDesc(TII->get(EVM::EQ_S)); + std::next(I)->eraseFromParent(); + return true; + } + + ++I; + } + return false; +} + +char EVMPeephole::ID = 0; + +INITIALIZE_PASS(EVMPeephole, DEBUG_TYPE, EVM_PEEPHOLE, false, false) + +FunctionPass *llvm::createEVMPeepholePass() { return new EVMPeephole(); } diff --git a/llvm/lib/Target/EVM/EVMTargetMachine.cpp b/llvm/lib/Target/EVM/EVMTargetMachine.cpp index f1cb29550769..012e07dfcb6b 100644 --- a/llvm/lib/Target/EVM/EVMTargetMachine.cpp +++ b/llvm/lib/Target/EVM/EVMTargetMachine.cpp @@ -48,15 +48,12 @@ extern "C" LLVM_EXTERNAL_VISIBILITY void LLVMInitializeEVMTarget() { // Register the target. const RegisterTargetMachine X(getTheEVMTarget()); auto &PR = *PassRegistry::getPassRegistry(); - initializeEVMAAWrapperPassPass(PR); - initializeEVMAllocaHoistingPass(PR); - initializeEVMBPStackificationPass(PR); initializeEVMCodegenPreparePass(PR); - initializeEVMExternalAAWrapperPass(PR); + initializeEVMAllocaHoistingPass(PR); initializeEVMLinkRuntimePass(PR); initializeEVMLowerIntrinsicsPass(PR); - initializeEVMLowerJumpUnlessPass(PR); initializeEVMOptimizeLiveIntervalsPass(PR); + initializeEVMPeepholePass(PR); initializeEVMRegColoringPass(PR); initializeEVMSingleUseExpressionPass(PR); initializeEVMSplitCriticalEdgesPass(PR); @@ -299,6 +296,8 @@ void EVMPassConfig::addPreEmitPass() { void EVMPassConfig::addPreEmitPass2() { addPass(createEVMLowerJumpUnless()); addPass(createEVMConstantUnfolding()); + if (getOptLevel() != CodeGenOptLevel::None) + addPass(createEVMPeepholePass()); } TargetPassConfig *EVMTargetMachine::createPassConfig(PassManagerBase &PM) { diff --git a/llvm/test/CodeGen/EVM/O0-pipeline.ll b/llvm/test/CodeGen/EVM/O0-pipeline.ll new file mode 100644 index 000000000000..02d77d8eeabf --- /dev/null +++ b/llvm/test/CodeGen/EVM/O0-pipeline.ll @@ -0,0 +1,86 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 5 +; RUN: llc -O0 -debug-pass=Structure < %s -o /dev/null 2>&1 | FileCheck %s +target triple = "evm" + +; REQUIRES: asserts + +; CHECK-LABEL: Pass Arguments: +; CHECK-NEXT: Target Library Information +; CHECK-NEXT: Target Pass Configuration +; CHECK-NEXT: Machine Module Information +; CHECK-NEXT: Target Transform Information +; CHECK-NEXT: Create Garbage Collector Module Metadata +; CHECK-NEXT: Assumption Cache Tracker +; CHECK-NEXT: Profile summary info +; CHECK-NEXT: Machine Branch Probability Analysis +; CHECK-NEXT: ModulePass Manager +; CHECK-NEXT: Pre-ISel Intrinsic Lowering +; CHECK-NEXT: EVM Lower Intrinsics +; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: Module Verifier +; CHECK-NEXT: Lower Garbage Collection Instructions +; CHECK-NEXT: Shadow Stack GC Lowering +; CHECK-NEXT: Lower constant intrinsics +; CHECK-NEXT: Remove unreachable blocks from the CFG +; CHECK-NEXT: Expand vector predication intrinsics +; CHECK-NEXT: Instrument function entry/exit with calls to e.g. mcount() (post inlining) +; CHECK-NEXT: Scalarize Masked Memory Intrinsics +; CHECK-NEXT: Expand reduction intrinsics +; CHECK-NEXT: Final transformations before code generation +; CHECK-NEXT: Lower invoke and unwind, for unwindless code generators +; CHECK-NEXT: Remove unreachable blocks from the CFG +; CHECK-NEXT: CallGraph Construction +; CHECK-NEXT: EVM mark recursive functions +; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: Prepare callbr +; CHECK-NEXT: Safe Stack instrumentation pass +; CHECK-NEXT: Insert stack protectors +; CHECK-NEXT: Module Verifier +; CHECK-NEXT: Assignment Tracking Analysis +; CHECK-NEXT: Unnamed pass: implement Pass::getPassName() +; CHECK-NEXT: EVM Argument Move +; CHECK-NEXT: Finalize ISel and expand pseudo-instructions +; CHECK-NEXT: Local Stack Slot Allocation +; CHECK-NEXT: Eliminate PHI nodes for register allocation +; CHECK-NEXT: Two-Address instruction pass +; CHECK-NEXT: Remove Redundant DEBUG_VALUE analysis +; CHECK-NEXT: Fixup Statepoint Caller Saved +; CHECK-NEXT: Lazy Machine Block Frequency Analysis +; CHECK-NEXT: Machine Optimization Remark Emitter +; CHECK-NEXT: Prologue/Epilogue Insertion & Frame Finalization +; CHECK-NEXT: Post-RA pseudo instruction expansion pass +; CHECK-NEXT: Insert fentry calls +; CHECK-NEXT: Insert XRay ops +; CHECK-NEXT: EVM split critical edges +; CHECK-NEXT: MachineDominator Tree Construction +; CHECK-NEXT: Slot index numbering +; CHECK-NEXT: Live Interval Analysis +; CHECK-NEXT: EVM Optimize Live Intervals +; CHECK-NEXT: EVM Single use expressions +; CHECK-NEXT: Slot index numbering +; CHECK-NEXT: Live Interval Analysis +; CHECK-NEXT: Machine Natural Loop Construction +; CHECK-NEXT: Virtual Register Map +; CHECK-NEXT: Live Stack Slot Analysis +; CHECK-NEXT: Machine Block Frequency Analysis +; CHECK-NEXT: EVM backward propagation stackification +; CHECK-NEXT: Stack Slot Coloring +; CHECK-NEXT: EVM finalize stack frames +; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: Machine Sanitizer Binary Metadata +; CHECK-NEXT: Lazy Machine Block Frequency Analysis +; CHECK-NEXT: Machine Optimization Remark Emitter +; CHECK-NEXT: Stack Frame Layout Analysis +; CHECK-NEXT: EVM Lower jump_unless +; CHECK-NEXT: EVM constant unfolding +; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: Lazy Machine Block Frequency Analysis +; CHECK-NEXT: Machine Optimization Remark Emitter +; CHECK-NEXT: EVM Assembly +; CHECK-NEXT: Free MachineFunction + +define void @f() { + ret void +} +;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line: +; CHECK: {{.*}} diff --git a/llvm/test/CodeGen/EVM/O3-pipeline.ll b/llvm/test/CodeGen/EVM/O3-pipeline.ll index c6f2605162ba..5185960da01a 100644 --- a/llvm/test/CodeGen/EVM/O3-pipeline.ll +++ b/llvm/test/CodeGen/EVM/O3-pipeline.ll @@ -147,6 +147,7 @@ target triple = "evm" ; CHECK-NEXT: EVM Lower jump_unless ; CHECK-NEXT: EVM constant unfolding ; CHECK-NEXT: FunctionPass Manager +; CHECK-NEXT: EVM Peephole ; CHECK-NEXT: Lazy Machine Block Frequency Analysis ; CHECK-NEXT: Machine Optimization Remark Emitter ; CHECK-NEXT: EVM Assembly diff --git a/llvm/test/CodeGen/EVM/brcond.ll b/llvm/test/CodeGen/EVM/brcond.ll index 193d2be5b7e2..305942f28712 100644 --- a/llvm/test/CodeGen/EVM/brcond.ll +++ b/llvm/test/CodeGen/EVM/brcond.ll @@ -423,3 +423,31 @@ false: unreachable } +define void @br_or(i256 %a, i256 %b, i256 %c) { +; CHECK-LABEL: br_or: +; CHECK: ; %bb.0: +; CHECK-NEXT: JUMPDEST +; CHECK-NEXT: SWAP3 +; CHECK-NEXT: POP +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: DUP3 +; CHECK-NEXT: SWAP1 +; CHECK-NEXT: EQ +; CHECK-NEXT: ISZERO +; CHECK-NEXT: SWAP2 +; CHECK-NEXT: SUB +; CHECK-NEXT: OR +; CHECK-NEXT: PUSH4 @.BB20_2 +; CHECK-NEXT: JUMPI +; CHECK-NEXT: ; %bb.1: ; %false +; CHECK-NEXT: .BB20_2: ; %true +; CHECK-NEXT: JUMPDEST + %cond1 = icmp ne i256 %a, %b + %cond2 = icmp ne i256 %a, %c + %cond = or i1 %cond1, %cond2 + br i1 %cond, label %true, label %false +false: + unreachable +true: + unreachable +} diff --git a/llvm/test/CodeGen/EVM/evm-peephole-negative.mir b/llvm/test/CodeGen/EVM/evm-peephole-negative.mir new file mode 100644 index 000000000000..20243b0166ac --- /dev/null +++ b/llvm/test/CodeGen/EVM/evm-peephole-negative.mir @@ -0,0 +1,85 @@ +# RUN: llc -x mir -mtriple=evm-unknown-unknown -run-pass=evm-peephole < %s | FileCheck %s + +--- | + target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" + target triple = "evm-unknown-unknown" + + define void @iszero_fallthrough() { + ret void + } + + define void @iszero_iszero_fallthrough() { + ret void + } + + define void @iszero_iszero_or_fallthrough() { + ret void + } +... +--- +name: iszero_fallthrough +liveins: + - { reg: '$arguments', virtual-reg: '' } + - { reg: '$value_stack', virtual-reg: '' } +body: | + bb.0: + successors: %bb.1(0x80000000) + liveins: $arguments, $value_stack + + ISZERO_S + + bb.1: + successors: + liveins: $value_stack + +... +--- +name: iszero_iszero_fallthrough +liveins: + - { reg: '$arguments', virtual-reg: '' } + - { reg: '$value_stack', virtual-reg: '' } +body: | + bb.0: + successors: %bb.1(0x80000000) + liveins: $arguments, $value_stack + + ISZERO_S + ISZERO_S + + bb.1: + successors: + liveins: $value_stack + +... +--- +name: iszero_iszero_or_fallthrough +liveins: + - { reg: '$arguments', virtual-reg: '' } + - { reg: '$value_stack', virtual-reg: '' } +body: | + bb.0: + successors: %bb.1(0x80000000) + liveins: $arguments, $value_stack + + ISZERO_S + ISZERO_S + OR_S + + bb.1: + successors: + liveins: $value_stack + +... + +# CHECK-LABEL: name: iszero_fallthrough +# CHECK: ISZERO_S +# +# CHECK-LABEL: name: iszero_iszero_fallthrough +# CHECK: ISZERO_S +# CHECK-NEXT: ISZERO_S +# +# CHECK-LABEL: name: iszero_iszero_or_fallthrough +# CHECK: ISZERO_S +# CHECK-NEXT: ISZERO_S +# CHECK-NEXT: OR_S + diff --git a/llvm/test/CodeGen/EVM/lower-jump-unless.mir b/llvm/test/CodeGen/EVM/lower-jump-unless.mir deleted file mode 100644 index 015fdebf103c..000000000000 --- a/llvm/test/CodeGen/EVM/lower-jump-unless.mir +++ /dev/null @@ -1,108 +0,0 @@ -# RUN: llc -x mir --run-pass=evm-lower-jump-unless < %s | FileCheck %s -# RUN: llc -x mir --run-pass=evm-lower-jump-unless -O0 < %s | FileCheck %s --check-prefix=CHECK-O0 - ---- | - target datalayout = "E-p:256:256-i256:256:256-S256-a:256:256" - target triple = "evm" - - define void @br_eq(i256 %a, i256 %b) { - %cond = icmp eq i256 %a, %b - br i1 %cond, label %true, label %false - - true: ; preds = %0 - unreachable - - false: ; preds = %0 - unreachable - } - - define void @br_ugt(i256 %a, i256 %b) { - %cond = icmp ugt i256 %a, %b - br i1 %cond, label %true, label %false - - true: ; preds = %0 - unreachable - - false: ; preds = %0 - unreachable - } - -... ---- -name: br_eq -alignment: 1 -machineFunctionInfo: - isStackified: true - numberOfParameters: 2 - hasPushDeployAddress: false -body: | - ; CHECK-LABEL: name: br_eq - ; CHECK: SWAP2_S - ; CHECK-NEXT: POP_S - ; CHECK-NEXT: SUB_S - ; CHECK-NEXT: PseudoJUMPI %bb.2 - ; - ; CHECK-O0-LABEL: name: br_eq - ; CHECK-O0: SWAP2_S - ; CHECK-O0-NEXT: POP_S - ; CHECK-O0-NEXT: EQ_S - ; CHECK-O0-NEXT: ISZERO_S - ; CHECK-O0-NEXT: PseudoJUMPI %bb.2 - bb.0 (%ir-block.0): - successors: %bb.1(0x40000000), %bb.2(0x40000000) - liveins: $arguments, $value_stack - - SWAP2_S - POP_S - EQ_S - PseudoJUMP_UNLESS %bb.2 - - bb.1.true: - successors: - liveins: $value_stack - - bb.2.false: - liveins: $value_stack - -... ---- -name: br_ugt -alignment: 1 -machineFunctionInfo: - isStackified: true - numberOfParameters: 2 - hasPushDeployAddress: false -body: | - ; CHECK-LABEL: name: br_ugt - ; CHECK: SWAP1_S - ; CHECK-NEXT: SWAP2_S - ; CHECK-NEXT: POP_S - ; CHECK-NEXT: UGT_S - ; CHECK-NEXT: ISZERO_S - ; CHECK-NEXT: PseudoJUMPI %bb.2 - ; - ; CHECK-O0-LABEL: name: br_ugt - ; CHECK-O0: SWAP1_S - ; CHECK-O0-NEXT: SWAP2_S - ; CHECK-O0-NEXT: POP_S - ; CHECK-O0-NEXT: UGT_S - ; CHECK-O0-NEXT: ISZERO_S - ; CHECK-O0-NEXT: PseudoJUMPI %bb.2 - bb.0 (%ir-block.0): - successors: %bb.1(0x40000000), %bb.2(0x40000000) - liveins: $arguments, $value_stack - - SWAP1_S - SWAP2_S - POP_S - UGT_S - PseudoJUMP_UNLESS %bb.2 - - bb.1.true: - successors: - liveins: $value_stack - - bb.2.false: - liveins: $value_stack - -...