https://github.com/saveasguy created https://github.com/llvm/llvm-project/pull/107834
None >From 5ca9c3f25663e78ea5205a901735b649756e9c1e Mon Sep 17 00:00:00 2001 From: Aleksei Romanov <raa_2...@mail.ru> Date: Wed, 20 Sep 2023 01:10:02 +0300 Subject: [PATCH 1/5] [LVN] Add tests on LVN Pass (NFC) --- llvm/include/llvm/Transforms/Scalar/LVN.h | 15 ++++++ llvm/lib/Passes/PassBuilder.cpp | 1 + llvm/lib/Passes/PassRegistry.def | 1 + llvm/lib/Transforms/Scalar/CMakeLists.txt | 1 + llvm/lib/Transforms/Scalar/LVN.cpp | 7 +++ llvm/test/Transforms/LVN/basic_tests.ll | 66 +++++++++++++++++++++++ 6 files changed, 91 insertions(+) create mode 100644 llvm/include/llvm/Transforms/Scalar/LVN.h create mode 100644 llvm/lib/Transforms/Scalar/LVN.cpp create mode 100644 llvm/test/Transforms/LVN/basic_tests.ll diff --git a/llvm/include/llvm/Transforms/Scalar/LVN.h b/llvm/include/llvm/Transforms/Scalar/LVN.h new file mode 100644 index 00000000000000..a99e81a5922c8a --- /dev/null +++ b/llvm/include/llvm/Transforms/Scalar/LVN.h @@ -0,0 +1,15 @@ +#ifndef LLVM_TRANSFORMS_SCALAR_LVN_H +#define LLVM_TRANSFORMS_SCALAR_LVN_H + +#include "llvm/IR/PassManager.h" + +namespace llvm { + +class LVNPass : public PassInfoMixin<LVNPass> { +public: + PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); +}; + +} // end namespace llvm + +#endif // LLVM_TRANSFORMS_SCALAR_LVN_H diff --git a/llvm/lib/Passes/PassBuilder.cpp b/llvm/lib/Passes/PassBuilder.cpp index 5c7f26109930c9..dc99c9408a20cd 100644 --- a/llvm/lib/Passes/PassBuilder.cpp +++ b/llvm/lib/Passes/PassBuilder.cpp @@ -201,6 +201,7 @@ #include "llvm/Transforms/Scalar/LowerGuardIntrinsic.h" #include "llvm/Transforms/Scalar/LowerMatrixIntrinsics.h" #include "llvm/Transforms/Scalar/LowerWidenableCondition.h" +#include "llvm/Transforms/Scalar/LVN.h" #include "llvm/Transforms/Scalar/MakeGuardsExplicit.h" #include "llvm/Transforms/Scalar/MemCpyOptimizer.h" #include "llvm/Transforms/Scalar/MergeICmps.h" diff --git a/llvm/lib/Passes/PassRegistry.def b/llvm/lib/Passes/PassRegistry.def index b9aa015d02dd95..1729eb6120db72 100644 --- a/llvm/lib/Passes/PassRegistry.def +++ b/llvm/lib/Passes/PassRegistry.def @@ -358,6 +358,7 @@ FUNCTION_PASS("loop-simplify", LoopSimplifyPass()) FUNCTION_PASS("loop-sink", LoopSinkPass()) FUNCTION_PASS("lowerinvoke", LowerInvokePass()) FUNCTION_PASS("lowerswitch", LowerSwitchPass()) +FUNCTION_PASS("lvn", LVNPass()) FUNCTION_PASS("mem2reg", PromotePass()) FUNCTION_PASS("memcpyopt", MemCpyOptPass()) FUNCTION_PASS("mergeicmps", MergeICmpsPass()) diff --git a/llvm/lib/Transforms/Scalar/CMakeLists.txt b/llvm/lib/Transforms/Scalar/CMakeLists.txt index eb008c15903a74..1f39809420e4c7 100644 --- a/llvm/lib/Transforms/Scalar/CMakeLists.txt +++ b/llvm/lib/Transforms/Scalar/CMakeLists.txt @@ -52,6 +52,7 @@ add_llvm_component_library(LLVMScalarOpts LowerGuardIntrinsic.cpp LowerMatrixIntrinsics.cpp LowerWidenableCondition.cpp + LVN.cpp MakeGuardsExplicit.cpp MemCpyOptimizer.cpp MergeICmps.cpp diff --git a/llvm/lib/Transforms/Scalar/LVN.cpp b/llvm/lib/Transforms/Scalar/LVN.cpp new file mode 100644 index 00000000000000..e5daccf0d78dd5 --- /dev/null +++ b/llvm/lib/Transforms/Scalar/LVN.cpp @@ -0,0 +1,7 @@ +#include "llvm/Transforms/Scalar/LVN.h" + +using namespace llvm; + +PreservedAnalyses LVNPass::run(Function &F, FunctionAnalysisManager &FAM) { + return PreservedAnalyses::all(); +} diff --git a/llvm/test/Transforms/LVN/basic_tests.ll b/llvm/test/Transforms/LVN/basic_tests.ll new file mode 100644 index 00000000000000..a3197101db694a --- /dev/null +++ b/llvm/test/Transforms/LVN/basic_tests.ll @@ -0,0 +1,66 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 3 +; RUN: opt -passes='lvn,dce' -S < %s | FileCheck %s + +define i32 @redundant_add(i32 %a, i32 %b, i32 %c) { +; CHECK-LABEL: define i32 @redundant_add( +; CHECK-SAME: i32 [[A:%.*]], i32 [[B:%.*]], i32 [[C:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]] +; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[B]], [[C]] +; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B]] +; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]] +; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[MUL2]], [[ADD1]] +; CHECK-NEXT: ret i32 [[ADD2]] +; +entry: + %add = add i32 %a, %b + %mul = mul i32 %b, %c + %add1 = add i32 %a, %b + %mul2 = mul i32 %add, %mul + %add2 = add i32 %mul2, %add1 + ret i32 %add2 +} + +define i32 @redundant_mul(i32 noundef %a, i32 noundef %b, i32 noundef %c) { +; CHECK-LABEL: define i32 @redundant_mul( +; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]] +; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[B]], [[C]] +; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[B]], [[C]] +; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]] +; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[MUL2]], [[MUL1]] +; CHECK-NEXT: ret i32 [[ADD1]] +; +entry: + %add = add i32 %a, %b + %mul = mul i32 %b, %c + %mul1 = mul i32 %b, %c + %mul2 = mul i32 %add, %mul + %add1 = add i32 %mul2, %mul1 + ret i32 %add1 +} + +define i32 @redundant_add_x2(i32 noundef %a, i32 noundef %b, i32 noundef %c) { +; CHECK-LABEL: define i32 @redundant_add_x2( +; CHECK-SAME: i32 noundef [[A:%.*]], i32 noundef [[B:%.*]], i32 noundef [[C:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]] +; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[B]], [[C]] +; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B]] +; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]] +; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[MUL2]], [[ADD1]] +; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[A]], [[B]] +; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD2]], [[ADD3]] +; CHECK-NEXT: ret i32 [[ADD4]] +; +entry: + %add = add i32 %a, %b + %mul = mul i32 %b, %c + %add1 = add i32 %a, %b + %mul2 = mul i32 %add, %mul + %add2 = add i32 %mul2, %add1 + %add3 = add i32 %a, %b + %add4 = add i32 %add2, %add3 + ret i32 %add4 +} >From 99e16678ad1933677a1234647f6326171ccbab01 Mon Sep 17 00:00:00 2001 From: Aleksei Romanov <raa_2...@mail.ru> Date: Wed, 20 Sep 2023 02:05:57 +0300 Subject: [PATCH 2/5] [LVN] Add simple LVN Pass --- llvm/include/llvm/Transforms/Scalar/LVN.h | 3 ++ llvm/lib/Transforms/Scalar/LVN.cpp | 43 +++++++++++++++++++++++ llvm/test/Transforms/LVN/basic_tests.ll | 12 +++---- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/llvm/include/llvm/Transforms/Scalar/LVN.h b/llvm/include/llvm/Transforms/Scalar/LVN.h index a99e81a5922c8a..de6feed0fc8837 100644 --- a/llvm/include/llvm/Transforms/Scalar/LVN.h +++ b/llvm/include/llvm/Transforms/Scalar/LVN.h @@ -8,6 +8,9 @@ namespace llvm { class LVNPass : public PassInfoMixin<LVNPass> { public: PreservedAnalyses run(Function &F, FunctionAnalysisManager &FAM); + +private: + void runOnBasicBlock(BasicBlock &BB); }; } // end namespace llvm diff --git a/llvm/lib/Transforms/Scalar/LVN.cpp b/llvm/lib/Transforms/Scalar/LVN.cpp index e5daccf0d78dd5..e774e6a472e6d9 100644 --- a/llvm/lib/Transforms/Scalar/LVN.cpp +++ b/llvm/lib/Transforms/Scalar/LVN.cpp @@ -1,7 +1,50 @@ #include "llvm/Transforms/Scalar/LVN.h" +#include <cstdint> +#include <tuple> +#include <unordered_map> + +#include "llvm/IR/InstrTypes.h" + using namespace llvm; +namespace { + +using InstrTupleTy = std::tuple<Instruction::BinaryOps, Value *, Value *>; + +struct InstrTupleHash { + size_t operator()(const InstrTupleTy &InstrTuple) const { + auto LHSPtrVal = reinterpret_cast<uintptr_t>(std::get<1>(InstrTuple)); + auto RHSPtrVal = reinterpret_cast<uintptr_t>(std::get<2>(InstrTuple)); + return std::get<0>(InstrTuple) ^ LHSPtrVal * RHSPtrVal; + } +}; + +} // end namespace + PreservedAnalyses LVNPass::run(Function &F, FunctionAnalysisManager &FAM) { + for (auto &BB : F) { + runOnBasicBlock(BB); + } return PreservedAnalyses::all(); } + +void LVNPass::runOnBasicBlock(BasicBlock &BB) { + std::unordered_map<InstrTupleTy, Value *, InstrTupleHash> InstrToValue; + for (auto &I : BB) { + BinaryOperator *BO = dyn_cast<BinaryOperator>(&I); + if (!BO) { + continue; + } + Value *RHS = BO->getOperand(0); + Value *LHS = BO->getOperand(1); + auto InstrTuple = std::make_tuple(BO->getOpcode(), RHS, LHS); + Value *BOValue = static_cast<Value *>(BO); + auto FoundInstrIt = InstrToValue.find(InstrTuple); + if (FoundInstrIt == InstrToValue.end()) { + InstrToValue.insert({InstrTuple, BOValue}); + } else { + BO->replaceAllUsesWith(FoundInstrIt->second); + } + } +} diff --git a/llvm/test/Transforms/LVN/basic_tests.ll b/llvm/test/Transforms/LVN/basic_tests.ll index a3197101db694a..3c1902d0c7501b 100644 --- a/llvm/test/Transforms/LVN/basic_tests.ll +++ b/llvm/test/Transforms/LVN/basic_tests.ll @@ -7,9 +7,8 @@ define i32 @redundant_add(i32 %a, i32 %b, i32 %c) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[B]], [[C]] -; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]] -; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[MUL2]], [[ADD1]] +; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[MUL2]], [[ADD]] ; CHECK-NEXT: ret i32 [[ADD2]] ; entry: @@ -27,9 +26,8 @@ define i32 @redundant_mul(i32 noundef %a, i32 noundef %b, i32 noundef %c) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[B]], [[C]] -; CHECK-NEXT: [[MUL1:%.*]] = mul i32 [[B]], [[C]] ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]] -; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[MUL2]], [[MUL1]] +; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[MUL2]], [[MUL]] ; CHECK-NEXT: ret i32 [[ADD1]] ; entry: @@ -47,11 +45,9 @@ define i32 @redundant_add_x2(i32 noundef %a, i32 noundef %b, i32 noundef %c) { ; CHECK-NEXT: entry: ; CHECK-NEXT: [[ADD:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: [[MUL:%.*]] = mul i32 [[B]], [[C]] -; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[A]], [[B]] ; CHECK-NEXT: [[MUL2:%.*]] = mul i32 [[ADD]], [[MUL]] -; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[MUL2]], [[ADD1]] -; CHECK-NEXT: [[ADD3:%.*]] = add i32 [[A]], [[B]] -; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD2]], [[ADD3]] +; CHECK-NEXT: [[ADD2:%.*]] = add i32 [[MUL2]], [[ADD]] +; CHECK-NEXT: [[ADD4:%.*]] = add i32 [[ADD2]], [[ADD]] ; CHECK-NEXT: ret i32 [[ADD4]] ; entry: >From d6ded34b82305bcf2af0a7e1af07e59a44003b63 Mon Sep 17 00:00:00 2001 From: Aleksei Romanov <raa_2...@mail.ru> Date: Sun, 24 Sep 2023 01:32:24 +0300 Subject: [PATCH 3/5] [RISCV][AsmParser] Pre-commit test: recognition of 'vsetvli' omitting LMUL (NFC) --- llvm/test/MC/RISCV/rvv/invalid.s | 3 +++ 1 file changed, 3 insertions(+) diff --git a/llvm/test/MC/RISCV/rvv/invalid.s b/llvm/test/MC/RISCV/rvv/invalid.s index 09fd2c3bebf035..e267d60a32a4b1 100644 --- a/llvm/test/MC/RISCV/rvv/invalid.s +++ b/llvm/test/MC/RISCV/rvv/invalid.s @@ -1,6 +1,9 @@ # RUN: not llvm-mc -triple=riscv64 --mattr=+v --mattr=+f %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-ERROR +vsetvli a2, 32, e8, ta, ma +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] + vsetivli a2, 32, e8,m1 # CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] >From 9e8ba6f33193aa5503484ba57bdc4bf6a9d899f6 Mon Sep 17 00:00:00 2001 From: Aleksei Romanov <raa_2...@mail.ru> Date: Sun, 24 Sep 2023 01:33:26 +0300 Subject: [PATCH 4/5] [RISCV][AsmParser] Recognition of 'vsetvli' omitting LMUL --- .../Target/RISCV/AsmParser/RISCVAsmParser.cpp | 13 ++++- llvm/test/MC/RISCV/rvv/invalid.s | 55 +++++++++---------- llvm/test/MC/RISCV/rvv/vsetvl.s | 6 ++ 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp index 7d8d82e381313b..ad9ca703e48bdf 100644 --- a/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp +++ b/llvm/lib/Target/RISCV/AsmParser/RISCVAsmParser.cpp @@ -2102,8 +2102,15 @@ bool RISCVAsmParser::parseVTypeToken(StringRef Identifier, VTypeState &State, State = VTypeState_LMUL; return false; case VTypeState_LMUL: { - if (!Identifier.consume_front("m")) - break; + if (!Identifier.consume_front("m")) { + Lmul = 1; + Fractional = false; + State = VTypeState_TailPolicy; + // Intentionally fall through parsing step + // since LMUL is omitted + return parseVTypeToken(Identifier, State, Sew, Lmul, Fractional, + TailAgnostic, MaskAgnostic); + } Fractional = Identifier.consume_front("f"); if (Identifier.getAsInteger(10, Lmul)) break; @@ -2189,7 +2196,7 @@ bool RISCVAsmParser::generateVTypeError(SMLoc ErrorLoc) { return Error( ErrorLoc, "operand must be " - "e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); + "e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu]"); } ParseStatus RISCVAsmParser::parseMaskReg(OperandVector &Operands) { diff --git a/llvm/test/MC/RISCV/rvv/invalid.s b/llvm/test/MC/RISCV/rvv/invalid.s index e267d60a32a4b1..c6a405cc38f8c5 100644 --- a/llvm/test/MC/RISCV/rvv/invalid.s +++ b/llvm/test/MC/RISCV/rvv/invalid.s @@ -1,87 +1,84 @@ # RUN: not llvm-mc -triple=riscv64 --mattr=+v --mattr=+f %s 2>&1 \ # RUN: | FileCheck %s --check-prefix=CHECK-ERROR -vsetvli a2, 32, e8, ta, ma -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] - vsetivli a2, 32, e8,m1 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetivli a2, zero, e8,m1 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetivli a2, 5, (1 << 10) -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetivli a2, 5, 0x400 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetivli a2, 5, e31 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, (1 << 11) -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, 0x800 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e31 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e32,m3 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, m1,e32 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e32,m16 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e2048,m8 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e1,m8 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,tx -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,ta,mx -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,ma -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,mu -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8x,m1,tu,mu -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1z,tu,mu -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,mf1,tu,mu -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,tu,mut -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,tut,mu -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1 -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,m1,ta -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vsetvli a2, a0, e8,1,ta,ma -# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],m[1|2|4|8|f2|f4|f8],[ta|tu],[ma|mu] +# CHECK-ERROR: operand must be e[8|16|32|64|128|256|512|1024],[m[1|2|4|8|f2|f4|f8],][ta|tu],[ma|mu] vadd.vv v1, v3, v2, v4.t # CHECK-ERROR: operand must be v0.t diff --git a/llvm/test/MC/RISCV/rvv/vsetvl.s b/llvm/test/MC/RISCV/rvv/vsetvl.s index bdf0553841b9ce..b0a31e79a2ab13 100644 --- a/llvm/test/MC/RISCV/rvv/vsetvl.s +++ b/llvm/test/MC/RISCV/rvv/vsetvl.s @@ -45,6 +45,12 @@ vsetvli a2, a0, 144 # CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' or 'Zve64x' (Vector Extensions for Embedded Processors){{$}} # CHECK-UNKNOWN: 57 76 05 09 <unknown> +vsetvli a2, a0, e32, ta, ma +# CHECK-INST: vsetvli a2, a0, e32, m1, ta, ma +# CHECK-ENCODING: [0x57,0x76,0x05,0x0d] +# CHECK-ERROR: instruction requires the following: 'V' (Vector Extension for Application Processors), 'Zve32x' or 'Zve64x' (Vector Extensions for Embedded Processors){{$}} +# CHECK-UNKNOWN: 57 76 05 0d <unknown> + vsetvli a2, a0, e32, m1, ta, ma # CHECK-INST: vsetvli a2, a0, e32, m1, ta, ma # CHECK-ENCODING: [0x57,0x76,0x05,0x0d] >From 288541009c6cf3f191f3102762e0666877633c4a Mon Sep 17 00:00:00 2001 From: Aleksei Romanov <raa_2...@mail.ru> Date: Mon, 9 Sep 2024 12:56:32 +0300 Subject: [PATCH 5/5] Double run offloading --- clang/include/clang/Driver/Options.td | 6 +++ clang/lib/Driver/Driver.cpp | 60 +++++++++++++++++++++++++++ 2 files changed, 66 insertions(+) diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td index 553c7928c4f949..0363f34ed790e1 100644 --- a/clang/include/clang/Driver/Options.td +++ b/clang/include/clang/Driver/Options.td @@ -6118,6 +6118,12 @@ def fno_sycl : Flag<["-"], "fno-sycl">, Flags<[NoXarchOption]>, Visibility<[ClangOption, CLOption]>, Group<sycl_Group>, HelpText<"Disables SYCL kernels compilation for device">; +// double run options +def fdoublerun : Flag<["-"], "fdoublerun">, + Group<f_Group>, HelpText<"Enables double run">; +def fno_doublerun : Flag<["-"], "fno-doublerun">, + Group<f_Group>, HelpText<"Disables double run">; + //===----------------------------------------------------------------------===// // FLangOption + NoXarchOption //===----------------------------------------------------------------------===// diff --git a/clang/lib/Driver/Driver.cpp b/clang/lib/Driver/Driver.cpp index 84b8fc7685fed4..c5794e9644e5bf 100644 --- a/clang/lib/Driver/Driver.cpp +++ b/clang/lib/Driver/Driver.cpp @@ -2865,6 +2865,64 @@ class OffloadingActionBuilder final { } }; + class MyActionBuilder : public DeviceActionBuilder { + Action *FirstRunAction; + public: + MyActionBuilder(Compilation &C, DerivedArgList &Args, + const Driver::InputList &Inputs) + : DeviceActionBuilder(C, Args, Inputs, Action::OFK_Host) {} + + bool initialize() override { + if (Args.hasFlag(options::OPT_fdoublerun, options::OPT_fno_doublerun, + false)) { + const ToolChain *TC = + C.getSingleOffloadToolChain<Action::OFK_Host>(); + ToolChains.push_back(TC); + return false; + } + return true; + } + + ActionBuilderReturnCode addDeviceDependences(Action *HostAction) override { + if (auto *IA = dyn_cast<InputAction>(HostAction)) { + FirstRunAction = C.MakeAction<InputAction>( + IA->getInputArg(), IA->getType(), IA->getId()); + return ABRT_Success; + } + return ABRT_Inactive; + } + + ActionBuilderReturnCode + getDeviceDependences(OffloadAction::DeviceDependences &DA, + phases::ID CurPhase, phases::ID FinalPhase, + PhasesTy &Phases) override { + if (CurPhase != phases::Backend) + return ABRT_Inactive; + + assert(FirstRunAction); + Action *PrevFirstRunAction = FirstRunAction; + for (auto Ph : Phases) { + if (Ph > CurPhase) + break; + FirstRunAction = C.getDriver().ConstructPhaseAction(C, Args, Ph, FirstRunAction); + // FirstRunAction + } + if (PrevFirstRunAction == FirstRunAction) + return ABRT_Inactive; + DA.add(*FirstRunAction, *ToolChains.front(), ToolChains.front()->getArchName().data(), Action::OFK_Host); + return ABRT_Success; + } + + StringRef getCanonicalOffloadArch(StringRef Arch) { + return Arch; + } + + std::optional<std::pair<StringRef, StringRef>> + getConflictOffloadArchCombination(const std::set<StringRef> &ArchSet) { + return std::nullopt; + } + }; + /// Base class for CUDA/HIP action builder. It injects device code in /// the host backend action. class CudaActionBuilderBase : public DeviceActionBuilder { @@ -3612,6 +3670,8 @@ class OffloadingActionBuilder final { // Create a specialized builder for HIP. SpecializedBuilders.push_back(new HIPActionBuilder(C, Args, Inputs)); + SpecializedBuilders.push_back(new MyActionBuilder(C, Args, Inputs)); + // // TODO: Build other specialized builders here. // _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits