diff --git a/llvm/docs/AMDGPUUsage.rst b/llvm/docs/AMDGPUUsage.rst index 9027120d1d4ae..ee501a5f14e32 100644 --- a/llvm/docs/AMDGPUUsage.rst +++ b/llvm/docs/AMDGPUUsage.rst @@ -2568,6 +2568,9 @@ As part of the AMDGPU MC layer, AMDGPU provides the following target-specific ``max(arg, ...)`` 1 or more Variadic signed operation that returns the maximum value of all its arguments. + ``min(arg, ...)`` 1 or more Variadic signed operation that returns the minimum + value of all its arguments + ``or(arg, ...)`` 1 or more Variadic signed operation that returns the bitwise-or result of all its arguments. diff --git a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp index bcfb105137af8..0a30f09fdeb37 100644 --- a/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp +++ b/llvm/lib/Target/AMDGPU/AsmParser/AMDGPUAsmParser.cpp @@ -9344,7 +9344,8 @@ void AMDGPUAsmParser::onBeginOfFile() { /// Parse AMDGPU specific expressions. /// /// expr ::= or(expr, ...) | -/// max(expr, ...) +/// max(expr, ...) | +/// min(expr, ...) /// bool AMDGPUAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { using AGVK = AMDGPUMCExpr::VariantKind; @@ -9353,6 +9354,7 @@ bool AMDGPUAsmParser::parsePrimaryExpr(const MCExpr *&Res, SMLoc &EndLoc) { StringRef TokenId = getTokenStr(); AGVK VK = StringSwitch(TokenId) .Case("max", AGVK::AGVK_Max) + .Case("min", AGVK::AGVK_Min) .Case("or", AGVK::AGVK_Or) .Case("extrasgprs", AGVK::AGVK_ExtraSGPRs) .Case("totalnumvgprs", AGVK::AGVK_TotalNumVGPRs) diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp index 08871f43a42b5..90ac9147b9eeb 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.cpp @@ -65,6 +65,9 @@ void AMDGPUMCExpr::printImpl(raw_ostream &OS, const MCAsmInfo *MAI) const { case AGVK_Max: OS << "max("; break; + case AGVK_Min: + OS << "min("; + break; case AGVK_ExtraSGPRs: OS << "extrasgprs("; break; @@ -103,6 +106,8 @@ static int64_t op(AMDGPUMCExpr::VariantKind Kind, int64_t Arg1, int64_t Arg2) { return std::max(Arg1, Arg2); case AMDGPUMCExpr::AGVK_Or: return Arg1 | Arg2; + case AMDGPUMCExpr::AGVK_Min: + return std::min(Arg1, Arg2); } } @@ -499,6 +504,16 @@ static void targetOpKnownBitsMapHelper(const MCExpr *Expr, KnownBitsMap &KBM, KBM[Expr] = std::move(KB); return; } + case AMDGPUMCExpr::VariantKind::AGVK_Min: { + knownBitsMapHelper(AGVK->getSubExpr(0), KBM, Depth + 1); + KnownBits KB = KBM[AGVK->getSubExpr(0)]; + for (const MCExpr *Arg : AGVK->getArgs()) { + knownBitsMapHelper(Arg, KBM, Depth + 1); + KB = KnownBits::umin(KB, KBM[Arg]); + } + KBM[Expr] = std::move(KB); + return; + } case AMDGPUMCExpr::VariantKind::AGVK_ExtraSGPRs: case AMDGPUMCExpr::VariantKind::AGVK_TotalNumVGPRs: case AMDGPUMCExpr::VariantKind::AGVK_AlignTo: diff --git a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h index 66b6fdb4b0042..369545fa79cea 100644 --- a/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h +++ b/llvm/lib/Target/AMDGPU/MCTargetDesc/AMDGPUMCExpr.h @@ -24,9 +24,11 @@ enum class LitModifier { None, Lit, Lit64 }; /// operations are: /// - (bitwise) or /// - max +/// - min /// -/// \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. +/// \note If the 'or'/'max'/'min' operations are provided only a single +/// argument, the operation will act as a no-op and simply resolve as the +/// provided argument. /// class AMDGPUMCExpr : public MCTargetExpr { public: @@ -41,6 +43,7 @@ class AMDGPUMCExpr : public MCTargetExpr { AGVK_InstPrefSize, AGVK_Lit, AGVK_Lit64, + AGVK_Min, }; // Relocation specifiers. @@ -85,6 +88,10 @@ class AMDGPUMCExpr : public MCTargetExpr { MCContext &Ctx) { return create(VariantKind::AGVK_Max, Args, Ctx); } + static const AMDGPUMCExpr *createMin(ArrayRef Args, + MCContext &Ctx) { + return create(VariantKind::AGVK_Min, Args, Ctx); + } static const AMDGPUMCExpr *createExtraSGPRs(const MCExpr *VCCUsed, const MCExpr *FlatScrUsed, diff --git a/llvm/test/MC/AMDGPU/mcexpr_amd.s b/llvm/test/MC/AMDGPU/mcexpr_amd.s index d7340bb5fd2ed..4423d56f50397 100644 --- a/llvm/test/MC/AMDGPU/mcexpr_amd.s +++ b/llvm/test/MC/AMDGPU/mcexpr_amd.s @@ -17,7 +17,6 @@ // 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 @@ -29,6 +28,24 @@ // 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: 0000000000000001 l *ABS* 0000000000000000 min_expression_all +// OBJDUMP-NEXT: 0000000000000001 l *ABS* 0000000000000000 min_expression_two +// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 min_expression_one +// OBJDUMP-NEXT: 0000000000000001 l *ABS* 0000000000000000 min_literals +// OBJDUMP-NEXT: 0000000000000000 l *ABS* 0000000000000000 min_with_min_sym +// OBJDUMP-NEXT: 0000000000000000 l *ABS* 0000000000000000 min +// OBJDUMP-NEXT: ffffffffffffffff l *ABS* 0000000000000000 neg_one +// OBJDUMP-NEXT: fffffffffffffffb l *ABS* 0000000000000000 min_neg_numbers +// OBJDUMP-NEXT: ffffffffffffffff l *ABS* 0000000000000000 min_neg_number +// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 min_with_subexpr +// OBJDUMP-NEXT: 0000000000000004 l *ABS* 0000000000000000 min_as_subexpr +// OBJDUMP-NEXT: 0000000000000001 l *ABS* 0000000000000000 min_recursive_subexpr +// OBJDUMP-NEXT: 7fffffffffffffff l *ABS* 0000000000000000 min_expr_one_max +// OBJDUMP-NEXT: 0000000000000003 l *ABS* 0000000000000000 min_expr_two_max +// OBJDUMP-NEXT: ffffffffff676980 l *ABS* 0000000000000000 min_expr_three_max +// OBJDUMP-NEXT: 8000000000000000 l *ABS* 0000000000000000 min_expr_one_min +// OBJDUMP-NEXT: 8000000000000000 l *ABS* 0000000000000000 min_expr_two_min +// OBJDUMP-NEXT: 8000000000000000 l *ABS* 0000000000000000 min_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 @@ -97,6 +114,49 @@ .set max_expr_two_min, max(i64_min, three) .set max_expr_three_min, max(i64_min, three, 10000000) +// ASM: .set min_expression_all, min(1, 2, five, 3, four) +// ASM: .set min_expression_two, 1 +// ASM: .set min_expression_one, 3 +// ASM: .set min_literals, 1 +// ASM: .set min_with_min_sym, min(min, 4, 3, 1, 2) + +.set min_expression_all, min(one, two, five, three, four) +.set min_expression_two, min(one, three) +.set min_expression_one, min(three) +.set min_literals, min(1,2,3,4,5,6,7,8,9,10) +.set min_with_min_sym, min(min, 4, 3, one, two) + +// ASM: .set min_neg_numbers, -5 +// ASM: .set min_neg_number, -1 + +.set neg_one, -1 +.set min_neg_numbers, min(-5, -4, -3, -2, neg_one) +.set min_neg_number, min(neg_one) + +// ASM: .set min_with_subexpr, 3 +// ASM: .set min_as_subexpr, 1+min(4, 3, five) +// ASM: .set min_recursive_subexpr, min(min(1, four), 3, min_expression_all) + +.set min_with_subexpr, min(((one | 3) << 3) / 8) +.set min_as_subexpr, 1 + min(4, 3, five) +.set min_recursive_subexpr, min(min(one, four), three, min_expression_all) + +// ASM: .set min_expr_one_max, 9223372036854775807 +// ASM: .set min_expr_two_max, 3 +// ASM: .set min_expr_three_max, -10000000 + +.set min_expr_one_max, min(i64_max) +.set min_expr_two_max, min(i64_max, three) +.set min_expr_three_max, min(i64_max, three, -10000000) + +// ASM: .set min_expr_one_min, -9223372036854775808 +// ASM: .set min_expr_two_min, min(-9223372036854775808, five) +// ASM: .set min_expr_three_min, min(-9223372036854775808, five, 10000000) + +.set min_expr_one_min, min(i64_min) +.set min_expr_two_min, min(i64_min, five) +.set min_expr_three_min, min(i64_min, five, 10000000) + // ASM: .set or_expression_all, or(1, 2, five, 3, four) // ASM: .set or_expression_two, 3 // ASM: .set or_expression_one, 1 @@ -127,4 +187,5 @@ .set four, 4 .set five, 5 .set max, 0xF +.set min, 0x0 .set or, 0xFF diff --git a/llvm/test/MC/AMDGPU/mcexpr_amd_err.s b/llvm/test/MC/AMDGPU/mcexpr_amd_err.s index 834c6eee8c31f..e97479688c5fe 100644 --- a/llvm/test/MC/AMDGPU/mcexpr_amd_err.s +++ b/llvm/test/MC/AMDGPU/mcexpr_amd_err.s @@ -8,6 +8,10 @@ // ASM: :[[@LINE-1]]:{{[0-9]+}}: error: empty max expression // ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression +.set min_empty, min() +// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: empty min 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 @@ -40,6 +44,10 @@ // ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token in or expression // ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression +.set min_expression_one, min(four,five +// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: unexpected token in min expression +// ASM: :[[@LINE-2]]:{{[0-9]+}}: error: missing expression + .set max_no_lparen, max four, five) // ASM: :[[@LINE-1]]:{{[0-9]+}}: error: expected newline @@ -49,5 +57,8 @@ .set max_rparen_only, max) // ASM: :[[@LINE-1]]:{{[0-9]+}}: error: expected newline +.set min_no_lparen, min four, five) +// ASM: :[[@LINE-1]]:{{[0-9]+}}: error: expected newline + .set four, 4 .set five, 5