Reland [AMDGPU] Add AMDGPU specific variadic operation MCExprs (#84562)
Adds AMDGPU specific variadic MCExpr operations 'max' and 'or'. Relands #82022 with fixes
This commit is contained in:
committed by
GitHub
parent
2d6988a45e
commit
f7bebc1914
@@ -1552,6 +1552,25 @@ The AMDGPU backend supports the following calling conventions:
|
||||
|
||||
=============================== ==========================================================
|
||||
|
||||
AMDGPU MCExpr
|
||||
-------------
|
||||
|
||||
As part of the AMDGPU MC layer, AMDGPU provides the following target specific
|
||||
``MCExpr``\s.
|
||||
|
||||
.. table:: AMDGPU MCExpr types:
|
||||
:name: amdgpu-mcexpr-table
|
||||
|
||||
=================== ================= ========================================================
|
||||
MCExpr Operands Return value
|
||||
=================== ================= ========================================================
|
||||
``max(arg, ...)`` 1 or more Variadic signed operation that returns the maximum
|
||||
value of all its arguments.
|
||||
|
||||
``or(arg, ...)`` 1 or more Variadic signed operation that returns the bitwise-or
|
||||
result of all its arguments.
|
||||
|
||||
=================== ================= ========================================================
|
||||
|
||||
.. _amdgpu-elf-code-object:
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AMDKernelCodeT.h"
|
||||
#include "MCTargetDesc/AMDGPUMCExpr.h"
|
||||
#include "MCTargetDesc/AMDGPUMCTargetDesc.h"
|
||||
#include "MCTargetDesc/AMDGPUTargetStreamer.h"
|
||||
#include "SIDefines.h"
|
||||
@@ -1816,6 +1817,7 @@ private:
|
||||
|
||||
public:
|
||||
void onBeginOfFile() override;
|
||||
bool parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) override;
|
||||
|
||||
ParseStatus parseCustomOperand(OperandVector &Operands, unsigned MCK);
|
||||
|
||||
@@ -8330,6 +8332,59 @@ void AMDGPUAsmParser::onBeginOfFile() {
|
||||
getTargetStreamer().EmitDirectiveAMDGCNTarget();
|
||||
}
|
||||
|
||||
/// Parse AMDGPU specific expressions.
|
||||
///
|
||||
/// expr ::= or(expr, ...) |
|
||||
/// max(expr, ...)
|
||||
///
|
||||
bool AMDGPUAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) {
|
||||
using AGVK = AMDGPUVariadicMCExpr::VariadicKind;
|
||||
|
||||
if (isToken(AsmToken::Identifier)) {
|
||||
StringRef TokenId = getTokenStr();
|
||||
AGVK VK = StringSwitch<AGVK>(TokenId)
|
||||
.Case("max", AGVK::AGVK_Max)
|
||||
.Case("or", AGVK::AGVK_Or)
|
||||
.Default(AGVK::AGVK_None);
|
||||
|
||||
if (VK != AGVK::AGVK_None && peekToken().is(AsmToken::LParen)) {
|
||||
SmallVector<const MCExpr *, 4> Exprs;
|
||||
uint64_t CommaCount = 0;
|
||||
lex(); // Eat 'max'/'or'
|
||||
lex(); // Eat '('
|
||||
while (true) {
|
||||
if (trySkipToken(AsmToken::RParen)) {
|
||||
if (Exprs.empty()) {
|
||||
Error(getToken().getLoc(),
|
||||
"empty " + Twine(TokenId) + " expression");
|
||||
return true;
|
||||
}
|
||||
if (CommaCount + 1 != Exprs.size()) {
|
||||
Error(getToken().getLoc(),
|
||||
"mismatch of commas in " + Twine(TokenId) + " expression");
|
||||
return true;
|
||||
}
|
||||
Res = AMDGPUVariadicMCExpr::create(VK, Exprs, getContext());
|
||||
return false;
|
||||
}
|
||||
const MCExpr *Expr;
|
||||
if (getParser().parseExpression(Expr, EndLoc))
|
||||
return true;
|
||||
Exprs.push_back(Expr);
|
||||
bool LastTokenWasComma = trySkipToken(AsmToken::Comma);
|
||||
if (LastTokenWasComma)
|
||||
CommaCount++;
|
||||
if (!LastTokenWasComma && !isToken(AsmToken::RParen)) {
|
||||
Error(getToken().getLoc(),
|
||||
"unexpected token in " + Twine(TokenId) + " expression");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return getParser().parsePrimaryExpr(Res, EndLoc, nullptr);
|
||||
}
|
||||
|
||||
ParseStatus AMDGPUAsmParser::parseOModSI(OperandVector &Operands) {
|
||||
StringRef Name = getTokenStr();
|
||||
if (Name == "mul") {
|
||||
|
||||
115
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
Normal file
115
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp
Normal file
@@ -0,0 +1,115 @@
|
||||
//===- AMDGPUMCExpr.cpp - AMDGPU specific MC expression classes -----------===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "AMDGPUMCExpr.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/MC/MCValue.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <optional>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
AMDGPUVariadicMCExpr::AMDGPUVariadicMCExpr(VariadicKind Kind,
|
||||
ArrayRef<const MCExpr *> Args,
|
||||
MCContext &Ctx)
|
||||
: Kind(Kind), Ctx(Ctx) {
|
||||
assert(Args.size() >= 1 && "Needs a minimum of one expression.");
|
||||
assert(Kind != AGVK_None &&
|
||||
"Cannot construct AMDGPUVariadicMCExpr of kind none.");
|
||||
|
||||
// Allocating the variadic arguments through the same allocation mechanism
|
||||
// that the object itself is allocated with so they end up in the same memory.
|
||||
//
|
||||
// Will result in an asan failure if allocated on the heap through standard
|
||||
// allocation (e.g., through SmallVector's grow).
|
||||
RawArgs = static_cast<const MCExpr **>(
|
||||
Ctx.allocate(sizeof(const MCExpr *) * Args.size()));
|
||||
std::uninitialized_copy(Args.begin(), Args.end(), RawArgs);
|
||||
this->Args = ArrayRef<const MCExpr *>(RawArgs, Args.size());
|
||||
}
|
||||
|
||||
AMDGPUVariadicMCExpr::~AMDGPUVariadicMCExpr() { Ctx.deallocate(RawArgs); }
|
||||
|
||||
const AMDGPUVariadicMCExpr *
|
||||
AMDGPUVariadicMCExpr::create(VariadicKind Kind, ArrayRef<const MCExpr *> Args,
|
||||
MCContext &Ctx) {
|
||||
return new (Ctx) AMDGPUVariadicMCExpr(Kind, Args, Ctx);
|
||||
}
|
||||
|
||||
const MCExpr *AMDGPUVariadicMCExpr::getSubExpr(size_t Index) const {
|
||||
assert(Index < Args.size() &&
|
||||
"Indexing out of bounds AMDGPUVariadicMCExpr sub-expr");
|
||||
return Args[Index];
|
||||
}
|
||||
|
||||
void AMDGPUVariadicMCExpr::printImpl(raw_ostream &OS,
|
||||
const MCAsmInfo *MAI) const {
|
||||
switch (Kind) {
|
||||
default:
|
||||
llvm_unreachable("Unknown AMDGPUVariadicMCExpr kind.");
|
||||
case AGVK_Or:
|
||||
OS << "or(";
|
||||
break;
|
||||
case AGVK_Max:
|
||||
OS << "max(";
|
||||
break;
|
||||
}
|
||||
for (auto It = Args.begin(); It != Args.end(); ++It) {
|
||||
(*It)->print(OS, MAI, /*InParens=*/false);
|
||||
if ((It + 1) != Args.end())
|
||||
OS << ", ";
|
||||
}
|
||||
OS << ')';
|
||||
}
|
||||
|
||||
static int64_t op(AMDGPUVariadicMCExpr::VariadicKind Kind, int64_t Arg1,
|
||||
int64_t Arg2) {
|
||||
switch (Kind) {
|
||||
default:
|
||||
llvm_unreachable("Unknown AMDGPUVariadicMCExpr kind.");
|
||||
case AMDGPUVariadicMCExpr::AGVK_Max:
|
||||
return std::max(Arg1, Arg2);
|
||||
case AMDGPUVariadicMCExpr::AGVK_Or:
|
||||
return Arg1 | Arg2;
|
||||
}
|
||||
}
|
||||
|
||||
bool AMDGPUVariadicMCExpr::evaluateAsRelocatableImpl(
|
||||
MCValue &Res, const MCAsmLayout *Layout, const MCFixup *Fixup) const {
|
||||
std::optional<int64_t> Total;
|
||||
|
||||
for (const MCExpr *Arg : Args) {
|
||||
MCValue ArgRes;
|
||||
if (!Arg->evaluateAsRelocatable(ArgRes, Layout, Fixup) ||
|
||||
!ArgRes.isAbsolute())
|
||||
return false;
|
||||
|
||||
if (!Total.has_value())
|
||||
Total = ArgRes.getConstant();
|
||||
Total = op(Kind, *Total, ArgRes.getConstant());
|
||||
}
|
||||
|
||||
Res = MCValue::get(*Total);
|
||||
return true;
|
||||
}
|
||||
|
||||
void AMDGPUVariadicMCExpr::visitUsedExpr(MCStreamer &Streamer) const {
|
||||
for (const MCExpr *Arg : Args)
|
||||
Streamer.visitUsedExpr(*Arg);
|
||||
}
|
||||
|
||||
MCFragment *AMDGPUVariadicMCExpr::findAssociatedFragment() const {
|
||||
for (const MCExpr *Arg : Args) {
|
||||
if (Arg->findAssociatedFragment())
|
||||
return Arg->findAssociatedFragment();
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
72
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
Normal file
72
llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h
Normal file
@@ -0,0 +1,72 @@
|
||||
//===- AMDGPUMCExpr.h - AMDGPU specific MC expression classes ---*- C++ -*-===//
|
||||
//
|
||||
// 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
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
|
||||
#define LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
|
||||
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/MC/MCExpr.h"
|
||||
|
||||
namespace llvm {
|
||||
|
||||
/// AMDGPU target specific variadic MCExpr operations.
|
||||
///
|
||||
/// Takes in a minimum of 1 argument to be used with an operation. The supported
|
||||
/// operations are:
|
||||
/// - (bitwise) or
|
||||
/// - max
|
||||
///
|
||||
/// \note If the 'or'/'max' operations are provided only a single argument, the
|
||||
/// operation will act as a no-op and simply resolve as the provided argument.
|
||||
///
|
||||
class AMDGPUVariadicMCExpr : public MCTargetExpr {
|
||||
public:
|
||||
enum VariadicKind { AGVK_None, AGVK_Or, AGVK_Max };
|
||||
|
||||
private:
|
||||
VariadicKind Kind;
|
||||
MCContext &Ctx;
|
||||
const MCExpr **RawArgs;
|
||||
ArrayRef<const MCExpr *> Args;
|
||||
|
||||
AMDGPUVariadicMCExpr(VariadicKind Kind, ArrayRef<const MCExpr *> Args,
|
||||
MCContext &Ctx);
|
||||
~AMDGPUVariadicMCExpr();
|
||||
|
||||
public:
|
||||
static const AMDGPUVariadicMCExpr *
|
||||
create(VariadicKind Kind, ArrayRef<const MCExpr *> Args, MCContext &Ctx);
|
||||
|
||||
static const AMDGPUVariadicMCExpr *createOr(ArrayRef<const MCExpr *> Args,
|
||||
MCContext &Ctx) {
|
||||
return create(VariadicKind::AGVK_Or, Args, Ctx);
|
||||
}
|
||||
|
||||
static const AMDGPUVariadicMCExpr *createMax(ArrayRef<const MCExpr *> Args,
|
||||
MCContext &Ctx) {
|
||||
return create(VariadicKind::AGVK_Max, Args, Ctx);
|
||||
}
|
||||
|
||||
VariadicKind getKind() const { return Kind; }
|
||||
const MCExpr *getSubExpr(size_t Index) const;
|
||||
|
||||
void printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const override;
|
||||
bool evaluateAsRelocatableImpl(MCValue &Res, const MCAsmLayout *Layout,
|
||||
const MCFixup *Fixup) const override;
|
||||
void visitUsedExpr(MCStreamer &Streamer) const override;
|
||||
MCFragment *findAssociatedFragment() const override;
|
||||
void fixELFSymbolsInTLSFixups(MCAssembler &) const override{};
|
||||
|
||||
static bool classof(const MCExpr *E) {
|
||||
return E->getKind() == MCExpr::Target;
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_AMDGPU_MCTARGETDESC_AMDGPUMCEXPR_H
|
||||
@@ -5,6 +5,7 @@ add_llvm_component_library(LLVMAMDGPUDesc
|
||||
AMDGPUInstPrinter.cpp
|
||||
AMDGPUMCAsmInfo.cpp
|
||||
AMDGPUMCCodeEmitter.cpp
|
||||
AMDGPUMCExpr.cpp
|
||||
AMDGPUMCTargetDesc.cpp
|
||||
AMDGPUTargetStreamer.cpp
|
||||
R600InstPrinter.cpp
|
||||
|
||||
130
llvm/test/MC/AMDGPU/mcexpr_amd.s
Normal file
130
llvm/test/MC/AMDGPU/mcexpr_amd.s
Normal file
@@ -0,0 +1,130 @@
|
||||
// RUN: llvm-mc -triple amdgcn-amd-amdhsa < %s | FileCheck --check-prefix=ASM %s
|
||||
// RUN: llvm-mc -triple amdgcn-amd-amdhsa -filetype=obj < %s > %t
|
||||
// RUN: llvm-objdump --syms %t | FileCheck --check-prefix=OBJDUMP %s
|
||||
|
||||
// OBJDUMP: SYMBOL TABLE:
|
||||
// OBJDUMP-NEXT: 0000000000000000 l *ABS* 0000000000000000 zero
|
||||
// OBJDUMP-NEXT: 0000000000000001 l *ABS* 0000000000000000 one
|
||||
// OBJDUMP-NEXT: 0000000000000002 l *ABS* 0000000000000000 two
|
||||
// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 three
|
||||
// OBJDUMP-NEXT: 7fffffffffffffff l *ABS* 0000000000000000 i64_max
|
||||
// OBJDUMP-NEXT: 8000000000000000 l *ABS* 0000000000000000 i64_min
|
||||
// OBJDUMP-NEXT: 0000000000000005 l *ABS* 0000000000000000 max_expression_all
|
||||
// OBJDUMP-NEXT: 0000000000000005 l *ABS* 0000000000000000 five
|
||||
// OBJDUMP-NEXT: 0000000000000004 l *ABS* 0000000000000000 four
|
||||
// OBJDUMP-NEXT: 0000000000000002 l *ABS* 0000000000000000 max_expression_two
|
||||
// OBJDUMP-NEXT: 0000000000000001 l *ABS* 0000000000000000 max_expression_one
|
||||
// OBJDUMP-NEXT: 000000000000000a l *ABS* 0000000000000000 max_literals
|
||||
// OBJDUMP-NEXT: 000000000000000f l *ABS* 0000000000000000 max_with_max_sym
|
||||
// OBJDUMP-NEXT: 000000000000000f l *ABS* 0000000000000000 max
|
||||
// OBJDUMP-NEXT: ffffffffffffffff l *ABS* 0000000000000000 neg_one
|
||||
// OBJDUMP-NEXT: ffffffffffffffff l *ABS* 0000000000000000 max_neg_numbers
|
||||
// OBJDUMP-NEXT: ffffffffffffffff l *ABS* 0000000000000000 max_neg_number
|
||||
// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 max_with_subexpr
|
||||
// OBJDUMP-NEXT: 0000000000000006 l *ABS* 0000000000000000 max_as_subexpr
|
||||
// OBJDUMP-NEXT: 0000000000000005 l *ABS* 0000000000000000 max_recursive_subexpr
|
||||
// OBJDUMP-NEXT: 7fffffffffffffff l *ABS* 0000000000000000 max_expr_one_max
|
||||
// OBJDUMP-NEXT: 7fffffffffffffff l *ABS* 0000000000000000 max_expr_two_max
|
||||
// OBJDUMP-NEXT: 7fffffffffffffff l *ABS* 0000000000000000 max_expr_three_max
|
||||
// OBJDUMP-NEXT: 8000000000000000 l *ABS* 0000000000000000 max_expr_one_min
|
||||
// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 max_expr_two_min
|
||||
// OBJDUMP-NEXT: 0000000000989680 l *ABS* 0000000000000000 max_expr_three_min
|
||||
// OBJDUMP-NEXT: 0000000000000007 l *ABS* 0000000000000000 or_expression_all
|
||||
// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 or_expression_two
|
||||
// OBJDUMP-NEXT: 0000000000000001 l *ABS* 0000000000000000 or_expression_one
|
||||
// OBJDUMP-NEXT: 000000000000000f l *ABS* 0000000000000000 or_literals
|
||||
// OBJDUMP-NEXT: 0000000000000000 l *ABS* 0000000000000000 or_false
|
||||
// OBJDUMP-NEXT: 00000000000000ff l *ABS* 0000000000000000 or_with_or_sym
|
||||
// OBJDUMP-NEXT: 00000000000000ff l *ABS* 0000000000000000 or
|
||||
// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 or_with_subexpr
|
||||
// OBJDUMP-NEXT: 0000000000000008 l *ABS* 0000000000000000 or_as_subexpr
|
||||
// OBJDUMP-NEXT: 0000000000000007 l *ABS* 0000000000000000 or_recursive_subexpr
|
||||
|
||||
// ASM: .set zero, 0
|
||||
// ASM: .set one, 1
|
||||
// ASM: .set two, 2
|
||||
// ASM: .set three, 3
|
||||
// ASM: .set i64_max, 9223372036854775807
|
||||
// ASM: .set i64_min, -9223372036854775808
|
||||
|
||||
.set zero, 0
|
||||
.set one, 1
|
||||
.set two, 2
|
||||
.set three, 3
|
||||
.set i64_max, 0x7FFFFFFFFFFFFFFF
|
||||
.set i64_min, 0x8000000000000000
|
||||
|
||||
// ASM: .set max_expression_all, max(1, 2, five, 3, four)
|
||||
// ASM: .set max_expression_two, 2
|
||||
// ASM: .set max_expression_one, 1
|
||||
// ASM: .set max_literals, 10
|
||||
// ASM: .set max_with_max_sym, max(max, 4, 3, 1, 2)
|
||||
|
||||
.set max_expression_all, max(one, two, five, three, four)
|
||||
.set max_expression_two, max(one, two)
|
||||
.set max_expression_one, max(one)
|
||||
.set max_literals, max(1,2,3,4,5,6,7,8,9,10)
|
||||
.set max_with_max_sym, max(max, 4, 3, one, two)
|
||||
|
||||
// ASM: .set max_neg_numbers, -1
|
||||
// ASM: .set max_neg_number, -1
|
||||
|
||||
.set neg_one, -1
|
||||
.set max_neg_numbers, max(-5, -4, -3, -2, neg_one)
|
||||
.set max_neg_number, max(neg_one)
|
||||
|
||||
// ASM: .set max_with_subexpr, 3
|
||||
// ASM: .set max_as_subexpr, 1+(max(4, 3, five))
|
||||
// ASM: .set max_recursive_subexpr, max(max(1, four), 3, max_expression_all)
|
||||
|
||||
.set max_with_subexpr, max(((one | 3) << 3) / 8)
|
||||
.set max_as_subexpr, 1 + max(4, 3, five)
|
||||
.set max_recursive_subexpr, max(max(one, four), three, max_expression_all)
|
||||
|
||||
// ASM: .set max_expr_one_max, 9223372036854775807
|
||||
// ASM: .set max_expr_two_max, max(9223372036854775807, five)
|
||||
// ASM: .set max_expr_three_max, max(9223372036854775807, five, 10000000)
|
||||
|
||||
.set max_expr_one_max, max(i64_max)
|
||||
.set max_expr_two_max, max(i64_max, five)
|
||||
.set max_expr_three_max, max(i64_max, five, 10000000)
|
||||
|
||||
// ASM: .set max_expr_one_min, -9223372036854775808
|
||||
// ASM: .set max_expr_two_min, 3
|
||||
// ASM: .set max_expr_three_min, 10000000
|
||||
|
||||
.set max_expr_one_min, max(i64_min)
|
||||
.set max_expr_two_min, max(i64_min, three)
|
||||
.set max_expr_three_min, max(i64_min, three, 10000000)
|
||||
|
||||
// ASM: .set or_expression_all, or(1, 2, five, 3, four)
|
||||
// ASM: .set or_expression_two, 3
|
||||
// ASM: .set or_expression_one, 1
|
||||
// ASM: .set or_literals, 15
|
||||
// ASM: .set or_false, 0
|
||||
// ASM: .set or_with_or_sym, or(or, 4, 3, 1, 2)
|
||||
|
||||
.set or_expression_all, or(one, two, five, three, four)
|
||||
.set or_expression_two, or(one, two)
|
||||
.set or_expression_one, or(one)
|
||||
.set or_literals, or(1,2,3,4,5,6,7,8,9,10)
|
||||
.set or_false, or(zero, 0, (2-2), 5 > 6)
|
||||
.set or_with_or_sym, or(or, 4, 3, one, two)
|
||||
|
||||
// ASM: .set or_with_subexpr, 3
|
||||
// ASM: .set or_as_subexpr, 1+(or(4, 3, five))
|
||||
// ASM: .set or_recursive_subexpr, or(or(1, four), 3, or_expression_all)
|
||||
|
||||
.set or_with_subexpr, or(((one | 3) << 3) / 8)
|
||||
.set or_as_subexpr, 1 + or(4, 3, five)
|
||||
.set or_recursive_subexpr, or(or(one, four), three, or_expression_all)
|
||||
|
||||
// ASM: .set four, 4
|
||||
// ASM: .set five, 5
|
||||
// ASM: .set max, 15
|
||||
// ASM: .set or, 255
|
||||
|
||||
.set four, 4
|
||||
.set five, 5
|
||||
.set max, 0xF
|
||||
.set or, 0xFF
|
||||
53
llvm/test/MC/AMDGPU/mcexpr_amd_err.s
Normal file
53
llvm/test/MC/AMDGPU/mcexpr_amd_err.s
Normal file
@@ -0,0 +1,53 @@
|
||||
// RUN: not llvm-mc -triple amdgcn-amd-amdhsa %s 2>&1 | FileCheck --check-prefix=ASM %s
|
||||
|
||||
.set one, 1
|
||||
.set two, 2
|
||||
.set three, 3
|
||||
|
||||
.set max_empty, max()
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: empty max expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set or_empty, or()
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: empty or expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_post_aux_comma, max(one,)
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: mismatch of commas in max expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_pre_aux_comma, max(,one)
|
||||
// asm: :[[@line-1]]:{{[0-9]+}}: error: unknown token in expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_double_comma, max(one,, two)
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unknown token in expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_no_comma, max(one two)
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token in max expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_missing_paren, max(two
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token in max expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_expression_one, max(three, four,
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unknown token in expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set or_expression_one, or(four, five
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token in or expression
|
||||
// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression
|
||||
|
||||
.set max_no_lparen, max four, five)
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: expected newline
|
||||
|
||||
.set max_no_paren, max one, two, three
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: expected newline
|
||||
|
||||
.set max_rparen_only, max)
|
||||
// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: expected newline
|
||||
|
||||
.set four, 4
|
||||
.set five, 5
|
||||
Reference in New Issue
Block a user