From 05598e3d3047cf028cc3e61f3268ff7d999e5f26 Mon Sep 17 00:00:00 2001 From: Daniel Kiss Date: Thu, 29 Oct 2020 14:00:40 +0100 Subject: [PATCH 01/11] [libunwind] Fix linker flag handling in the tests. --export-dynamic is not always available on all targets. -funwind-tables was a duplicate in the lit.site.cfg.in. Reviewed By: ldionne Differential Revision: https://reviews.llvm.org/D90202 --- libunwind/test/libunwind/test/config.py | 3 +++ libunwind/test/lit.site.cfg.in | 4 ---- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/libunwind/test/libunwind/test/config.py b/libunwind/test/libunwind/test/config.py index 977f9a0fb3f93f..9231860fc622d8 100644 --- a/libunwind/test/libunwind/test/config.py +++ b/libunwind/test/libunwind/test/config.py @@ -43,6 +43,9 @@ def configure_compile_flags(self): # Stack unwinding tests need unwinding tables and these are not # generated by default on all Targets. self.cxx.compile_flags += ['-funwind-tables'] + # Make symbols available in the tests. + if 'linux' in self.config.target_triple: + self.cxx.link_flags += ['-Wl,--export-dynamic'] if not self.get_lit_bool('enable_threads', True): self.cxx.compile_flags += ['-D_LIBUNWIND_HAS_NO_THREADS'] self.config.available_features.add('libunwind-no-threads') diff --git a/libunwind/test/lit.site.cfg.in b/libunwind/test/lit.site.cfg.in index 84dae3c2bfb0da..8ff770fe29bc86 100644 --- a/libunwind/test/lit.site.cfg.in +++ b/libunwind/test/lit.site.cfg.in @@ -44,10 +44,6 @@ config.test_source_root = os.path.join(config.libunwind_src_root, 'test') # Allow expanding substitutions that are based on other substitutions config.recursiveExpansionLimit = 10 -# Make symbols available in the tests. -config.test_compiler_flags += " -funwind-tables " -config.test_linker_flags += " -Wl,--export-dynamic " - # Infer the test_exec_root from the build directory. config.test_exec_root = os.path.join(config.libunwind_obj_root, 'test') From fd1c064845e598387b33ad4f548fde141f44728e Mon Sep 17 00:00:00 2001 From: Daniel Kiss Date: Thu, 29 Oct 2020 14:03:30 +0100 Subject: [PATCH 02/11] [libcxx] Add targets to available features. This patch add the target-* (x86_64-*) as used elsewhere in llvm. Reviewed By: #libc, #libc_abi, ldionne Differential Revision: https://reviews.llvm.org/D88027 --- libcxx/utils/libcxx/test/config.py | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/libcxx/utils/libcxx/test/config.py b/libcxx/utils/libcxx/test/config.py index 0d21aa17afd279..cb94e3c26f4c4b 100644 --- a/libcxx/utils/libcxx/test/config.py +++ b/libcxx/utils/libcxx/test/config.py @@ -266,6 +266,21 @@ def configure_features(self): self.config.available_features.add('libcxx_gdb') self.cxx.libcxx_gdb = libcxx_gdb + target_triple = getattr(self.config, 'target_triple', None) + if target_triple: + if re.match(r'^x86_64.*-apple', target_triple): + self.config.available_features.add('x86_64-apple') + if re.match(r'^x86_64.*-linux', target_triple): + self.config.available_features.add('x86_64-linux') + if re.match(r'^i.86.*', target_triple): + self.config.available_features.add('target-x86') + elif re.match(r'^x86_64.*', target_triple): + self.config.available_features.add('target-x86_64') + elif re.match(r'^aarch64.*', target_triple): + self.config.available_features.add('target-aarch64') + elif re.match(r'^arm.*', target_triple): + self.config.available_features.add('target-arm') + def configure_compile_flags(self): self.configure_default_compile_flags() # Configure extra flags From 6648414b2b7dd3802e6931be2f657926b97d0764 Mon Sep 17 00:00:00 2001 From: Marek Kurdej Date: Thu, 29 Oct 2020 14:39:09 +0100 Subject: [PATCH 03/11] [libcxx] [docs] [NFC] Fix typo. --- libcxx/docs/TestingLibcxx.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libcxx/docs/TestingLibcxx.rst b/libcxx/docs/TestingLibcxx.rst index d42becfd5c3d8b..b628fee538b8c5 100644 --- a/libcxx/docs/TestingLibcxx.rst +++ b/libcxx/docs/TestingLibcxx.rst @@ -187,7 +187,7 @@ few requirements to the test suite. Here's some stuff you should know: - All tests are run in a temporary directory that is unique to that test and cleaned up after the test is done. - When a test needs data files as inputs, these data files can be saved in the - repository (when reasonable) and referrenced by the test as + repository (when reasonable) and referenced by the test as ``// FILE_DEPENDENCIES: ``. Copies of these files or directories will be made available to the test in the temporary directory where it is run. From 75ba29ac5654b622107653a0fd33f84846b4e39f Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 29 Oct 2020 09:53:10 -0400 Subject: [PATCH 04/11] [flang][openacc] Enforce no modifier on enter data and exit data clauses Enter data can have the copyin clause and exit data can have the copyout clause. Both clauses support modifier with other directive but for these two directives no modifier are supported. This semantic check enforce this rule. Reviewed By: kiranktp Differential Revision: https://reviews.llvm.org/D90280 --- flang/lib/Semantics/check-acc-structure.cpp | 17 +++++++++++++++++ flang/lib/Semantics/check-acc-structure.h | 2 ++ flang/test/Semantics/acc-clause-validity.f90 | 5 ++++- 3 files changed, 23 insertions(+), 1 deletion(-) diff --git a/flang/lib/Semantics/check-acc-structure.cpp b/flang/lib/Semantics/check-acc-structure.cpp index 8adb15e9bc5ce0..4559050e693534 100644 --- a/flang/lib/Semantics/check-acc-structure.cpp +++ b/flang/lib/Semantics/check-acc-structure.cpp @@ -121,6 +121,19 @@ class NoBranchingEnforce { llvm::acc::Directive currentDirective_; }; +bool AccStructureChecker::CheckAllowedModifier(llvm::acc::Clause clause) { + if (GetContext().directive == llvm::acc::ACCD_enter_data || + GetContext().directive == llvm::acc::ACCD_exit_data) { + context_.Say(GetContext().clauseSource, + "Modifier is not allowed for the %s clause " + "on the %s directive"_err_en_US, + parser::ToUpperCaseLetters(getClauseName(clause).str()), + ContextDirectiveAsFortran()); + return true; + } + return false; +} + void AccStructureChecker::Enter(const parser::AccClause &x) { SetContextClause(x); } @@ -375,6 +388,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyin &c) { const auto &modifierClause{c.v}; if (const auto &modifier{ std::get>(modifierClause.t)}) { + if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyin)) + return; if (modifier->v != parser::AccDataModifier::Modifier::ReadOnly) { context_.Say(GetContext().clauseSource, "Only the READONLY modifier is allowed for the %s clause " @@ -392,6 +407,8 @@ void AccStructureChecker::Enter(const parser::AccClause::Copyout &c) { const auto &modifierClause{c.v}; if (const auto &modifier{ std::get>(modifierClause.t)}) { + if (CheckAllowedModifier(llvm::acc::Clause::ACCC_copyout)) + return; if (modifier->v != parser::AccDataModifier::Modifier::Zero) { context_.Say(GetContext().clauseSource, "Only the ZERO modifier is allowed for the %s clause " diff --git a/flang/lib/Semantics/check-acc-structure.h b/flang/lib/Semantics/check-acc-structure.h index f45878bbad66f0..4373ffc60a919f 100644 --- a/flang/lib/Semantics/check-acc-structure.h +++ b/flang/lib/Semantics/check-acc-structure.h @@ -115,6 +115,8 @@ class AccStructureChecker const llvm::acc::Directive directive, const parser::CharBlock &directiveSource) const; + bool CheckAllowedModifier(llvm::acc::Clause clause); + llvm::StringRef getClauseName(llvm::acc::Clause clause) override; llvm::StringRef getDirectiveName(llvm::acc::Directive directive) override; }; diff --git a/flang/test/Semantics/acc-clause-validity.f90 b/flang/test/Semantics/acc-clause-validity.f90 index 188d41f6e2a4e5..3cc1ca28aa497f 100644 --- a/flang/test/Semantics/acc-clause-validity.f90 +++ b/flang/test/Semantics/acc-clause-validity.f90 @@ -45,9 +45,12 @@ program openacc_clause_validity !ERROR: At least one of ATTACH, COPYIN, CREATE clause must appear on the ENTER DATA directive !$acc enter data - !ERROR: Only the READONLY modifier is allowed for the COPYIN clause on the ENTER DATA directive + !ERROR: Modifier is not allowed for the COPYIN clause on the ENTER DATA directive !$acc enter data copyin(zero: i) + !ERROR: Modifier is not allowed for the COPYOUT clause on the EXIT DATA directive + !$acc exit data copyout(zero: i) + !ERROR: Only the ZERO modifier is allowed for the CREATE clause on the ENTER DATA directive !$acc enter data create(readonly: i) From 1ce5f8bbb6f3fb581fd4c5905e5574c8b9a09268 Mon Sep 17 00:00:00 2001 From: Valentin Clement Date: Thu, 29 Oct 2020 09:54:31 -0400 Subject: [PATCH 05/11] [mlir][openacc] Add if and device_type to update op Update op is modelling the update directive (2.14.4) from the OpenACC specs. An if condition and a device_type list can be attached to the directive. This patch add these two information to the current op. Reviewed By: rriddle Differential Revision: https://reviews.llvm.org/D90310 --- mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td | 5 +++++ mlir/test/Dialect/OpenACC/ops.mlir | 6 ++++++ 2 files changed, 11 insertions(+) diff --git a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td index 7ed84000a694f1..ccc623377ea652 100644 --- a/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td +++ b/mlir/include/mlir/Dialect/OpenACC/OpenACCOps.td @@ -482,13 +482,18 @@ def OpenACC_UpdateOp : OpenACC_Op<"update", [AttrSizedOperandSegments]> { Variadic:$waitOperands, UnitAttr:$async, UnitAttr:$wait, + Variadic:$deviceTypeOperands, + Optional:$ifCond, Variadic:$hostOperands, Variadic:$deviceOperands, UnitAttr:$ifPresent); let assemblyFormat = [{ + ( `if` `(` $ifCond^ `)` )? ( `async` `(` $asyncOperand^ `:` type($asyncOperand) `)` )? ( `wait_devnum` `(` $waitDevnum^ `:` type($waitDevnum) `)` )? + ( `device_type` `(` $deviceTypeOperands^ `:` + type($deviceTypeOperands) `)` )? ( `wait` `(` $waitOperands^ `:` type($waitOperands) `)` )? ( `host` `(` $hostOperands^ `:` type($hostOperands) `)` )? ( `device` `(` $deviceOperands^ `:` type($deviceOperands) `)` )? diff --git a/mlir/test/Dialect/OpenACC/ops.mlir b/mlir/test/Dialect/OpenACC/ops.mlir index 01089ffbc77be1..6e5336727a651a 100644 --- a/mlir/test/Dialect/OpenACC/ops.mlir +++ b/mlir/test/Dialect/OpenACC/ops.mlir @@ -531,10 +531,13 @@ func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32> %i64Value = constant 1 : i64 %i32Value = constant 1 : i32 %idxValue = constant 1 : index + %ifCond = constant true acc.update async(%i64Value: i64) host(%a: memref<10xf32>) acc.update async(%i32Value: i32) host(%a: memref<10xf32>) acc.update async(%idxValue: index) host(%a: memref<10xf32>) acc.update wait_devnum(%i64Value: i64) wait(%i32Value, %idxValue : i32, index) host(%a: memref<10xf32>) + acc.update if(%ifCond) host(%a: memref<10xf32>) + acc.update device_type(%i32Value : i32) host(%a: memref<10xf32>) acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {async} acc.update host(%a: memref<10xf32>) device(%b, %c : memref<10xf32>, memref<10x10xf32>) attributes {wait} @@ -546,10 +549,13 @@ func @testupdateop(%a: memref<10xf32>, %b: memref<10xf32>, %c: memref<10x10xf32> // CHECK: [[I64VALUE:%.*]] = constant 1 : i64 // CHECK: [[I32VALUE:%.*]] = constant 1 : i32 // CHECK: [[IDXVALUE:%.*]] = constant 1 : index +// CHECK: [[IFCOND:%.*]] = constant true // CHECK: acc.update async([[I64VALUE]] : i64) host([[ARGA]] : memref<10xf32>) // CHECK: acc.update async([[I32VALUE]] : i32) host([[ARGA]] : memref<10xf32>) // CHECK: acc.update async([[IDXVALUE]] : index) host([[ARGA]] : memref<10xf32>) // CHECK: acc.update wait_devnum([[I64VALUE]] : i64) wait([[I32VALUE]], [[IDXVALUE]] : i32, index) host([[ARGA]] : memref<10xf32>) +// CHECK: acc.update if([[IFCOND]]) host([[ARGA]] : memref<10xf32>) +// CHECK: acc.update device_type([[I32VALUE]] : i32) host([[ARGA]] : memref<10xf32>) // CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) // CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {async} // CHECK: acc.update host([[ARGA]] : memref<10xf32>) device([[ARGB]], [[ARGC]] : memref<10xf32>, memref<10x10xf32>) attributes {wait} From 07d199660104b3e2e5e6e3f06412cfe66f9a6b61 Mon Sep 17 00:00:00 2001 From: "Kazushi (Jam) Marukawa" Date: Thu, 29 Oct 2020 20:38:04 +0900 Subject: [PATCH 06/11] [VE] Support register aliases in llvm-mc Support register aliases in MC layer to compile existing assembly files with clang and integrated assembler. Reviewed By: simoll Differential Revision: https://reviews.llvm.org/D90383 --- llvm/lib/Target/VE/VERegisterInfo.td | 19 +++++++++++++++---- llvm/test/MC/VE/register.s | 26 ++++++++++++++++++++++++++ 2 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 llvm/test/MC/VE/register.s diff --git a/llvm/lib/Target/VE/VERegisterInfo.td b/llvm/lib/Target/VE/VERegisterInfo.td index 312796143b2f4a..4e0efc302b485f 100644 --- a/llvm/lib/Target/VE/VERegisterInfo.td +++ b/llvm/lib/Target/VE/VERegisterInfo.td @@ -112,10 +112,21 @@ foreach I = 0-63 in DwarfRegNum<[I]>; // Generic integer registers - 64 bits wide -let SubRegIndices = [sub_i32, sub_f32], CoveredBySubRegs = 1 in -foreach I = 0-63 in - def SX#I : VEReg("SW"#I), !cast("SF"#I)], - ["s"#I]>, DwarfRegNum<[I]>; +let SubRegIndices = [sub_i32, sub_f32], CoveredBySubRegs = 1 in { + // Several registers have specific names, so add them to one of aliases. + def SX8 : VEReg<8, "s8", [SW8, SF8], ["s8", "sl"]>, DwarfRegNum<[8]>; + def SX9 : VEReg<9, "s9", [SW9, SF9], ["s9", "fp"]>, DwarfRegNum<[9]>; + def SX10 : VEReg<10, "s10", [SW10, SF10], ["s10", "lr"]>, DwarfRegNum<[10]>; + def SX11 : VEReg<11, "s11", [SW11, SF11], ["s11", "sp"]>, DwarfRegNum<[11]>; + def SX14 : VEReg<14, "s14", [SW14, SF14], ["s14", "tp"]>, DwarfRegNum<[14]>; + def SX15 : VEReg<15, "s15", [SW15, SF15], ["s15", "got"]>, DwarfRegNum<[15]>; + def SX16 : VEReg<16, "s16", [SW16, SF16], ["s16", "plt"]>, DwarfRegNum<[16]>; + + // Other generic registers. + foreach I = { 0-7, 12-13, 17-63 } in + def SX#I : VEReg("SW"#I), !cast("SF"#I)], + ["s"#I]>, DwarfRegNum<[I]>; +} // Aliases of the S* registers used to hold 128-bit for values (long doubles). // Following foreach represents something like: diff --git a/llvm/test/MC/VE/register.s b/llvm/test/MC/VE/register.s new file mode 100644 index 00000000000000..f2451785b72f18 --- /dev/null +++ b/llvm/test/MC/VE/register.s @@ -0,0 +1,26 @@ +# RUN: llvm-mc -triple=ve %s -o - | FileCheck %s +# RUN: llvm-mc -triple=ve -filetype=obj < %s | llvm-objdump -d - \ +# RUN: | FileCheck %s --check-prefixes=CHECK-INST + +### Test registers with specific names like "%sp" + + subu.l %fp, %sp, %s0 + brge.l.t %sp, %sl, 1f + ld %s63, 0x18(,%tp) +1: + or %got, 0, %plt + b.l (,%lr) + + +# CHECK: subu.l %s9, %s11, %s0 +# CHECK-NEXT: brge.l.t %s11, %s8, .Ltmp0 +# CHECK-NEXT: ld %s63, 24(, %s14) +# CHECK-NEXT: .Ltmp0: +# CHECK-NEXT: or %s15, 0, %s16 +# CHECK-NEXT: b.l (, %s10) + +# CHECK-INST: subu.l %s9, %s11, %s0 +# CHECK-INST-NEXT: brge.l.t %s11, %s8, 16 +# CHECK-INST-NEXT: ld %s63, 24(, %s14) +# CHECK-INST-NEXT: or %s15, 0, %s16 +# CHECK-INST-NEXT: b.l (, %s10) From f52c1b53310a1715b85b358a5c3de0e1f7c2e227 Mon Sep 17 00:00:00 2001 From: "Kazushi (Jam) Marukawa" Date: Thu, 29 Oct 2020 21:01:16 +0900 Subject: [PATCH 07/11] [VE] Add missing symbolic branch patterns Add missing symbolic branch patterns to a regression test. Reviewed By: simoll Differential Revision: https://reviews.llvm.org/D90388 --- llvm/test/MC/VE/sym-br.s | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/llvm/test/MC/VE/sym-br.s b/llvm/test/MC/VE/sym-br.s index 87800b518b0639..8e054791de74ae 100644 --- a/llvm/test/MC/VE/sym-br.s +++ b/llvm/test/MC/VE/sym-br.s @@ -1,10 +1,16 @@ # RUN: llvm-mc -triple=ve %s -o - | FileCheck %s # RUN: llvm-mc -triple=ve -filetype=obj %s -o - | llvm-objdump -r - | FileCheck %s --check-prefix=CHECK-OBJ + b.l.t tgt + br.l.t tgt2 b.l.t tgt(, %s1) b.l.t tgt+24(, %s1) -# CHECK: b.l.t tgt(, %s1) +# CHECK: b.l.t tgt +# CHECK-NEXT: br.l.t tgt2 +# CHECK-NEXT: b.l.t tgt(, %s1) # CHECK-NEXT: b.l.t tgt+24(, %s1) # CHECK-OBJ: 0 R_VE_REFLONG tgt -# CHECK-OBJ-NEXT: 8 R_VE_REFLONG tgt+0x18 +# CHECK-OBJ: 8 R_VE_PC_LO32 tgt2 +# CHECK-OBJ: 10 R_VE_REFLONG tgt +# CHECK-OBJ: 18 R_VE_REFLONG tgt+0x18 From 637c77fda64a9b4c021be9c2f89fe8995613c7ed Mon Sep 17 00:00:00 2001 From: Nico Weber Date: Thu, 29 Oct 2020 10:29:53 -0400 Subject: [PATCH 08/11] Revert "clang-format: Add a consumer to diagnostics engine" This reverts commit df00267f1fdb0b098dc42f1caa8a59b29c8e0e5f. clang-format should not depend on Frontend, see comment on https://reviews.llvm.org/D90121. --- clang/tools/clang-format/CMakeLists.txt | 1 - clang/tools/clang-format/ClangFormat.cpp | 7 ++----- 2 files changed, 2 insertions(+), 6 deletions(-) diff --git a/clang/tools/clang-format/CMakeLists.txt b/clang/tools/clang-format/CMakeLists.txt index 28ac4fb5913e73..35ecdb11253ce0 100644 --- a/clang/tools/clang-format/CMakeLists.txt +++ b/clang/tools/clang-format/CMakeLists.txt @@ -7,7 +7,6 @@ add_clang_tool(clang-format set(CLANG_FORMAT_LIB_DEPS clangBasic clangFormat - clangFrontend clangRewrite clangToolingCore ) diff --git a/clang/tools/clang-format/ClangFormat.cpp b/clang/tools/clang-format/ClangFormat.cpp index d7b768329bcc63..3a7247deab46df 100644 --- a/clang/tools/clang-format/ClangFormat.cpp +++ b/clang/tools/clang-format/ClangFormat.cpp @@ -18,7 +18,6 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Version.h" #include "clang/Format/Format.h" -#include "clang/Frontend/TextDiagnosticPrinter.h" #include "clang/Rewrite/Core/Rewriter.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" @@ -424,11 +423,9 @@ static bool format(StringRef FileName) { IntrusiveRefCntPtr InMemoryFileSystem( new llvm::vfs::InMemoryFileSystem); FileManager Files(FileSystemOptions(), InMemoryFileSystem); - IntrusiveRefCntPtr DiagOpts(new DiagnosticOptions()); - TextDiagnosticPrinter DiagnosticsConsumer(errs(), &*DiagOpts); DiagnosticsEngine Diagnostics( - IntrusiveRefCntPtr(new DiagnosticIDs), &*DiagOpts, - &DiagnosticsConsumer, false); + IntrusiveRefCntPtr(new DiagnosticIDs), + new DiagnosticOptions); SourceManager Sources(Diagnostics, Files); FileID ID = createInMemoryFile(AssumedFileName, Code.get(), Sources, Files, InMemoryFileSystem.get()); From 58a6b7bcdee24d72879d1c19331479ae94af6d41 Mon Sep 17 00:00:00 2001 From: "Kazushi (Jam) Marukawa" Date: Thu, 29 Oct 2020 20:57:00 +0900 Subject: [PATCH 09/11] [VE] Add missing BCR format Add missing "BCR %sy, 0, target" format instruction and a regression test for this format. Reviewed By: simoll Differential Revision: https://reviews.llvm.org/D90387 --- llvm/lib/Target/VE/VEInstrInfo.td | 25 +++++++++++++++++++------ llvm/test/MC/VE/BCR.s | 8 ++++++++ 2 files changed, 27 insertions(+), 6 deletions(-) diff --git a/llvm/lib/Target/VE/VEInstrInfo.td b/llvm/lib/Target/VE/VEInstrInfo.td index df3a4477aefebc..e0223586bad19d 100644 --- a/llvm/lib/Target/VE/VEInstrInfo.td +++ b/llvm/lib/Target/VE/VEInstrInfo.td @@ -205,6 +205,12 @@ def mimm : Operand, PatLeaf<(imm), [{ let PrintMethod = "printMImmOperand"; } +// zerofp - Generic fp immediate zero value. +def zerofp : Operand, PatLeaf<(fpimm), [{ + return getFpImmVal(N) == 0; }]> { + let ParserMatchClass = ZeroAsmOperand; +} + // simm7fp - Generic fp immediate value. def simm7fp : Operand, PatLeaf<(fpimm), [{ return isInt<7>(getFpImmVal(N)); @@ -827,10 +833,17 @@ multiclass BCRbpfm opc, dag cond> { !strconcat(opcStr, ".t ", cmpStr, "$imm32")>; } multiclass BCRm opc, - RegisterClass RC, Operand immOp> { + RegisterClass RC, Operand immOp, Operand zeroOp> { defm rr : BCRbpfm; let cy = 0 in - defm ir : BCRbpfm; + defm ir : BCRbpfm; + let cz = 0 in + defm rz : BCRbpfm; + let cy = 0, cz = 0 in + defm iz : BCRbpfm; let cy = 0, sy = 0, cz = 0, sz = 0, cf = 15 /* AT */, isBarrier = 1 in defm a : BCRbpfm; let cy = 0, sy = 0, cz = 0, sz = 0, cf = 0 /* AF */ in @@ -1409,13 +1422,13 @@ defm BCFS : BCm<"b${cond}.s", "b.s", "baf.s", 0x1C, F32, simm7fp>; // Section 8.8.4 - BCR (Branch on Condition Relative) let cx = 0, cx2 = 0 in -defm BRCFL : BCRm<"br${cf}.l", "br.l", "braf.l", 0x18, I64, simm7>; +defm BRCFL : BCRm<"br${cf}.l", "br.l", "braf.l", 0x18, I64, simm7, zero>; let cx = 1, cx2 = 0 in -defm BRCFW : BCRm<"br${cf}.w", "br.w", "braf.w", 0x18, I32, simm7>; +defm BRCFW : BCRm<"br${cf}.w", "br.w", "braf.w", 0x18, I32, simm7, zero>; let cx = 0, cx2 = 1 in -defm BRCFD : BCRm<"br${cf}.d", "br.d", "braf.d", 0x18, I64, simm7fp>; +defm BRCFD : BCRm<"br${cf}.d", "br.d", "braf.d", 0x18, I64, simm7fp, zerofp>; let cx = 1, cx2 = 1 in -defm BRCFS : BCRm<"br${cf}.s", "br.s", "braf.s", 0x18, F32, simm7fp>; +defm BRCFS : BCRm<"br${cf}.s", "br.s", "braf.s", 0x18, F32, simm7fp, zerofp>; // Section 8.8.5 - BSIC (Branch and Save IC) let isCall = 1, hasSideEffects = 0, DecoderMethod = "DecodeCall" in diff --git a/llvm/test/MC/VE/BCR.s b/llvm/test/MC/VE/BCR.s index 016e13630d1db0..b20c4c40dc40ca 100644 --- a/llvm/test/MC/VE/BCR.s +++ b/llvm/test/MC/VE/BCR.s @@ -19,6 +19,10 @@ braf.d.nt 224 # CHECK-ENCODING: encoding: [0xe0,0x00,0x00,0x00,0x94,0x17,0xc1,0x18] brgt.s 23, %s20, 224 +# CHECK-INST: brlt.l %s18, 0, -224 +# CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x00,0x92,0x02,0x18] +brlt.l %s18, 0, -224 + # CHECK-INST: brlt.l.t 23, %s20, -224 # CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x94,0x17,0x32,0x18] brlt.l.t 23, %s20, -224 @@ -31,6 +35,10 @@ brne.w.nt 23, %s20, 8192 # CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x94,0x17,0x44,0x18] breq.d 23, %s20, -224 +# CHECK-INST: breq.d %s20, 0, -224 +# CHECK-ENCODING: encoding: [0x20,0xff,0xff,0xff,0x00,0x94,0x44,0x18] +breq.d %s20, 0, -224 + # CHECK-INST: brge.s.t 23, %s20, 8192 # CHECK-ENCODING: encoding: [0x00,0x20,0x00,0x00,0x94,0x17,0xf5,0x18] brge.s.t 23, %s20, 8192 From 8c058dd2d752f9ac26a085eb93e1b6e864583be0 Mon Sep 17 00:00:00 2001 From: David Sherwood Date: Mon, 26 Oct 2020 15:12:58 +0000 Subject: [PATCH 10/11] [SVE] Remove TypeSize comparison operators All known instances in the code where we relied upon the TypeSize comparison operators have now been changed to either use scalar interger comparisons or one of the TypeSize::isKnownXY functions. It is now safe to remove the comparison operators. Differential Revision: https://reviews.llvm.org/D90160 --- llvm/include/llvm/Support/TypeSize.h | 19 ------------------- 1 file changed, 19 deletions(-) diff --git a/llvm/include/llvm/Support/TypeSize.h b/llvm/include/llvm/Support/TypeSize.h index 47fb90d21c0bae..392dd1a3360598 100644 --- a/llvm/include/llvm/Support/TypeSize.h +++ b/llvm/include/llvm/Support/TypeSize.h @@ -206,25 +206,6 @@ class TypeSize : public PolySize { uint64_t getFixedSize() const { return getFixedValue(); } uint64_t getKnownMinSize() const { return getKnownMinValue(); } - friend bool operator<(const TypeSize &LHS, const TypeSize &RHS) { - assert(LHS.IsScalable == RHS.IsScalable && - "Ordering comparison of scalable and fixed types"); - - return LHS.MinVal < RHS.MinVal; - } - - friend bool operator>(const TypeSize &LHS, const TypeSize &RHS) { - return RHS < LHS; - } - - friend bool operator<=(const TypeSize &LHS, const TypeSize &RHS) { - return !(RHS < LHS); - } - - friend bool operator>=(const TypeSize &LHS, const TypeSize& RHS) { - return !(LHS < RHS); - } - TypeSize &operator-=(TypeSize RHS) { assert(IsScalable == RHS.IsScalable && "Subtraction using mixed scalable and fixed types"); From dbae3d50f114a8ec0a7c3211e3b1b9fb6ef22dbd Mon Sep 17 00:00:00 2001 From: Frederik Gossen Date: Thu, 29 Oct 2020 13:48:07 +0000 Subject: [PATCH 11/11] [MLIR] Support walks over regions and blocks Add specializations for `walk` to allow traversal of regions and blocks. Differential Revision: https://reviews.llvm.org/D90379 --- mlir/include/mlir/Analysis/Liveness.h | 2 +- mlir/include/mlir/IR/Block.h | 4 +- mlir/include/mlir/IR/Operation.h | 2 +- mlir/include/mlir/IR/Visitors.h | 50 ++++++++++++------ mlir/lib/Analysis/Liveness.cpp | 44 ++++++---------- mlir/lib/IR/Visitors.cpp | 76 ++++++++++++++++++++++----- 6 files changed, 114 insertions(+), 64 deletions(-) diff --git a/mlir/include/mlir/Analysis/Liveness.h b/mlir/include/mlir/Analysis/Liveness.h index be9cb7166b8f0a..3bd298a0fbe74b 100644 --- a/mlir/include/mlir/Analysis/Liveness.h +++ b/mlir/include/mlir/Analysis/Liveness.h @@ -86,7 +86,7 @@ class Liveness { private: /// Initializes the internal mappings. - void build(MutableArrayRef regions); + void build(); private: /// The operation this analysis was constructed from. diff --git a/mlir/include/mlir/IR/Block.h b/mlir/include/mlir/IR/Block.h index ca2523050b242d..f65967ec628467 100644 --- a/mlir/include/mlir/IR/Block.h +++ b/mlir/include/mlir/IR/Block.h @@ -254,7 +254,7 @@ class Block : public IRObjectWithUseList, typename std::enable_if::value, RetT>::type walk(Block::iterator begin, Block::iterator end, FnT &&callback) { for (auto &op : llvm::make_early_inc_range(llvm::make_range(begin, end))) - detail::walkOperations(&op, callback); + detail::walk(&op, callback); } /// Walk the operations in the specified [begin, end) range of this block in @@ -265,7 +265,7 @@ class Block : public IRObjectWithUseList, typename std::enable_if::value, RetT>::type walk(Block::iterator begin, Block::iterator end, FnT &&callback) { for (auto &op : llvm::make_early_inc_range(llvm::make_range(begin, end))) - if (detail::walkOperations(&op, callback).wasInterrupted()) + if (detail::walk(&op, callback).wasInterrupted()) return WalkResult::interrupt(); return WalkResult::advance(); } diff --git a/mlir/include/mlir/IR/Operation.h b/mlir/include/mlir/IR/Operation.h index d3dce868ca646e..fa54cb608cf5dc 100644 --- a/mlir/include/mlir/IR/Operation.h +++ b/mlir/include/mlir/IR/Operation.h @@ -520,7 +520,7 @@ class Operation final /// }); template > RetT walk(FnT &&callback) { - return detail::walkOperations(this, std::forward(callback)); + return detail::walk(this, std::forward(callback)); } //===--------------------------------------------------------------------===// diff --git a/mlir/include/mlir/IR/Visitors.h b/mlir/include/mlir/IR/Visitors.h index 490ba92662a29e..cf7b3fa5db1c47 100644 --- a/mlir/include/mlir/IR/Visitors.h +++ b/mlir/include/mlir/IR/Visitors.h @@ -21,6 +21,8 @@ namespace mlir { class Diagnostic; class InFlightDiagnostic; class Operation; +class Block; +class Region; /// A utility result that is used to signal if a walk method should be /// interrupted or advance. @@ -61,31 +63,41 @@ decltype(first_argument_type(&F::operator())) first_argument_type(F); template using first_argument = decltype(first_argument_type(std::declval())); -/// Walk all of the operations nested under and including the given operation. -void walkOperations(Operation *op, function_ref callback); +/// Walk all of the regions, blocks, or operations nested under (and including) +/// the given operation. +void walk(Operation *op, function_ref callback); +void walk(Operation *op, function_ref callback); +void walk(Operation *op, function_ref callback); -/// Walk all of the operations nested under and including the given operation. -/// This methods walks operations until an interrupt result is returned by the -/// callback. -WalkResult walkOperations(Operation *op, - function_ref callback); +/// Walk all of the regions, blocks, or operations nested under (and including) +/// the given operation. These functions walk until an interrupt result is +/// returned by the callback. +WalkResult walk(Operation *op, function_ref callback); +WalkResult walk(Operation *op, function_ref callback); +WalkResult walk(Operation *op, function_ref callback); // Below are a set of functions to walk nested operations. Users should favor // the direct `walk` methods on the IR classes(Operation/Block/etc) over these // methods. They are also templated to allow for statically dispatching based // upon the type of the callback function. -/// Walk all of the operations nested under and including the given operation. -/// This method is selected for callbacks that operate on Operation*. +/// Walk all of the regions, blocks, or operations nested under (and including) +/// the given operation. This method is selected for callbacks that operate on +/// Region*, Block*, and Operation*. /// /// Example: +/// op->walk([](Region *r) { ... }); +/// op->walk([](Block *b) { ... }); /// op->walk([](Operation *op) { ... }); template < typename FuncTy, typename ArgT = detail::first_argument, typename RetT = decltype(std::declval()(std::declval()))> -typename std::enable_if::value, RetT>::type -walkOperations(Operation *op, FuncTy &&callback) { - return detail::walkOperations(op, function_ref(callback)); +typename std::enable_if::value || + std::is_same::value || + std::is_same::value, + RetT>::type +walk(Operation *op, FuncTy &&callback) { + return walk(op, function_ref(callback)); } /// Walk all of the operations of type 'ArgT' nested under and including the @@ -98,14 +110,16 @@ template < typename FuncTy, typename ArgT = detail::first_argument, typename RetT = decltype(std::declval()(std::declval()))> typename std::enable_if::value && + !std::is_same::value && + !std::is_same::value && std::is_same::value, RetT>::type -walkOperations(Operation *op, FuncTy &&callback) { +walk(Operation *op, FuncTy &&callback) { auto wrapperFn = [&](Operation *op) { if (auto derivedOp = dyn_cast(op)) callback(derivedOp); }; - return detail::walkOperations(op, function_ref(wrapperFn)); + return walk(op, function_ref(wrapperFn)); } /// Walk all of the operations of type 'ArgT' nested under and including the @@ -122,20 +136,22 @@ template < typename FuncTy, typename ArgT = detail::first_argument, typename RetT = decltype(std::declval()(std::declval()))> typename std::enable_if::value && + !std::is_same::value && + !std::is_same::value && std::is_same::value, RetT>::type -walkOperations(Operation *op, FuncTy &&callback) { +walk(Operation *op, FuncTy &&callback) { auto wrapperFn = [&](Operation *op) { if (auto derivedOp = dyn_cast(op)) return callback(derivedOp); return WalkResult::advance(); }; - return detail::walkOperations(op, function_ref(wrapperFn)); + return walk(op, function_ref(wrapperFn)); } /// Utility to provide the return type of a templated walk method. template -using walkResultType = decltype(walkOperations(nullptr, std::declval())); +using walkResultType = decltype(walk(nullptr, std::declval())); } // end namespace detail } // namespace mlir diff --git a/mlir/lib/Analysis/Liveness.cpp b/mlir/lib/Analysis/Liveness.cpp index 38fb386f8000c0..4dae386e94b263 100644 --- a/mlir/lib/Analysis/Liveness.cpp +++ b/mlir/lib/Analysis/Liveness.cpp @@ -125,31 +125,17 @@ struct BlockInfoBuilder { }; } // namespace -/// Walks all regions (including nested regions recursively) and invokes the -/// given function for every block. -template -static void walkRegions(MutableArrayRef regions, const FuncT &func) { - for (Region ®ion : regions) - for (Block &block : region) { - func(block); - - // Traverse all nested regions. - for (Operation &operation : block) - walkRegions(operation.getRegions(), func); - } -} - /// Builds the internal liveness block mapping. -static void buildBlockMapping(MutableArrayRef regions, +static void buildBlockMapping(Operation *operation, DenseMap &builders) { llvm::SetVector toProcess; - walkRegions(regions, [&](Block &block) { + operation->walk([&](Block *block) { BlockInfoBuilder &builder = - builders.try_emplace(&block, &block).first->second; + builders.try_emplace(block, block).first->second; if (builder.updateLiveIn()) - toProcess.insert(block.pred_begin(), block.pred_end()); + toProcess.insert(block->pred_begin(), block->pred_end()); }); // Propagate the in and out-value sets (fixpoint iteration) @@ -172,14 +158,14 @@ static void buildBlockMapping(MutableArrayRef regions, /// Creates a new Liveness analysis that computes liveness information for all /// associated regions. -Liveness::Liveness(Operation *op) : operation(op) { build(op->getRegions()); } +Liveness::Liveness(Operation *op) : operation(op) { build(); } /// Initializes the internal mappings. -void Liveness::build(MutableArrayRef regions) { +void Liveness::build() { // Build internal block mapping. DenseMap builders; - buildBlockMapping(regions, builders); + buildBlockMapping(operation, builders); // Store internal block data. for (auto &entry : builders) { @@ -284,11 +270,11 @@ void Liveness::print(raw_ostream &os) const { DenseMap blockIds; DenseMap operationIds; DenseMap valueIds; - walkRegions(operation->getRegions(), [&](Block &block) { - blockIds.insert({&block, blockIds.size()}); - for (BlockArgument argument : block.getArguments()) + operation->walk([&](Block *block) { + blockIds.insert({block, blockIds.size()}); + for (BlockArgument argument : block->getArguments()) valueIds.insert({argument, valueIds.size()}); - for (Operation &operation : block) { + for (Operation &operation : *block) { operationIds.insert({&operation, operationIds.size()}); for (Value result : operation.getResults()) valueIds.insert({result, valueIds.size()}); @@ -318,9 +304,9 @@ void Liveness::print(raw_ostream &os) const { }; // Dump information about in and out values. - walkRegions(operation->getRegions(), [&](Block &block) { - os << "// - Block: " << blockIds[&block] << "\n"; - auto liveness = getLiveness(&block); + operation->walk([&](Block *block) { + os << "// - Block: " << blockIds[block] << "\n"; + const auto *liveness = getLiveness(block); os << "// --- LiveIn: "; printValueRefs(liveness->inValues); os << "\n// --- LiveOut: "; @@ -329,7 +315,7 @@ void Liveness::print(raw_ostream &os) const { // Print liveness intervals. os << "// --- BeginLiveness"; - for (Operation &op : block) { + for (Operation &op : *block) { if (op.getNumResults() < 1) continue; os << "\n"; diff --git a/mlir/lib/IR/Visitors.cpp b/mlir/lib/IR/Visitors.cpp index bbccdcbf75928e..d03bdb508d373b 100644 --- a/mlir/lib/IR/Visitors.cpp +++ b/mlir/lib/IR/Visitors.cpp @@ -11,31 +11,79 @@ using namespace mlir; -/// Walk all of the operations nested under and including the given operations. -void detail::walkOperations(Operation *op, - function_ref callback) { +/// Walk all of the regions/blocks/operations nested under and including the +/// given operation. +void detail::walk(Operation *op, function_ref callback) { + for (auto ®ion : op->getRegions()) { + callback(®ion); + for (auto &block : region) { + for (auto &nestedOp : block) + walk(&nestedOp, callback); + } + } +} + +void detail::walk(Operation *op, function_ref callback) { + for (auto ®ion : op->getRegions()) { + for (auto &block : region) { + callback(&block); + for (auto &nestedOp : block) + walk(&nestedOp, callback); + } + } +} + +void detail::walk(Operation *op, function_ref callback) { // TODO: This walk should be iterative over the operations. - for (auto ®ion : op->getRegions()) - for (auto &block : region) + for (auto ®ion : op->getRegions()) { + for (auto &block : region) { // Early increment here in the case where the operation is erased. for (auto &nestedOp : llvm::make_early_inc_range(block)) - walkOperations(&nestedOp, callback); - + walk(&nestedOp, callback); + } + } callback(op); } -/// Walk all of the operations nested under and including the given operations. -/// This methods walks operations until an interrupt signal is received. -WalkResult -detail::walkOperations(Operation *op, - function_ref callback) { +/// Walk all of the regions/blocks/operations nested under and including the +/// given operation. These functions walk operations until an interrupt result +/// is returned by the callback. +WalkResult detail::walk(Operation *op, + function_ref callback) { + for (auto ®ion : op->getRegions()) { + if (callback(®ion).wasInterrupted()) + return WalkResult::interrupt(); + for (auto &block : region) { + for (auto &nestedOp : block) + walk(&nestedOp, callback); + } + } + return WalkResult::advance(); +} + +WalkResult detail::walk(Operation *op, + function_ref callback) { + for (auto ®ion : op->getRegions()) { + for (auto &block : region) { + if (callback(&block).wasInterrupted()) + return WalkResult::interrupt(); + for (auto &nestedOp : block) + walk(&nestedOp, callback); + } + } + return WalkResult::advance(); +} + +WalkResult detail::walk(Operation *op, + function_ref callback) { // TODO: This walk should be iterative over the operations. for (auto ®ion : op->getRegions()) { for (auto &block : region) { // Early increment here in the case where the operation is erased. - for (auto &nestedOp : llvm::make_early_inc_range(block)) - if (walkOperations(&nestedOp, callback).wasInterrupted()) + for (auto &nestedOp : llvm::make_early_inc_range(block)) { + if (walk(&nestedOp, callback).wasInterrupted()) return WalkResult::interrupt(); + } } } return callback(op);