diff --git a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td --- a/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td +++ b/llvm/lib/Target/LoongArch/LoongArchInstrInfo.td @@ -202,24 +202,32 @@ let DecoderMethod = "decodeSImmOperand<21, 2>"; } -// TODO: Need split the ParserMethod/PredicateMethod for call/jump/tailcall. -def SImm26Operand: AsmOperandClass { - let Name = "SImm26Operand"; +def SImm26OperandB: AsmOperandClass { + let Name = "SImm26OperandB"; + let PredicateMethod = "isSImm26Operand"; let RenderMethod = "addImmOperands"; let DiagnosticType = "InvalidSImm26Operand"; - let ParserMethod = "parseSImm26Operand"; + let ParserMethod = "parseImmediate"; } // A symbol or an imm used in B/PseudoBR. def simm26_b : Operand { - let ParserMatchClass = SImm26Operand; + let ParserMatchClass = SImm26OperandB; let EncoderMethod = "getImmOpValueAsr2"; let DecoderMethod = "decodeSImmOperand<26, 2>"; } +def SImm26OperandBL: AsmOperandClass { + let Name = "SImm26OperandBL"; + let PredicateMethod = "isSImm26Operand"; + let RenderMethod = "addImmOperands"; + let DiagnosticType = "InvalidSImm26Operand"; + let ParserMethod = "parseSImm26Operand"; +} + // A symbol or an imm used in BL/PseudoCALL. def simm26_bl : Operand { - let ParserMatchClass = SImm26Operand; + let ParserMatchClass = SImm26OperandBL; let EncoderMethod = "getImmOpValueAsr2"; let DecoderMethod = "decodeSImmOperand<26, 2>"; } diff --git a/llvm/test/CodeGen/LoongArch/blockaddress-symbol.ll b/llvm/test/CodeGen/LoongArch/blockaddress-symbol.ll new file mode 100644 --- /dev/null +++ b/llvm/test/CodeGen/LoongArch/blockaddress-symbol.ll @@ -0,0 +1,25 @@ +; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py +; RUN: llc --mtriple=loongarch32 < %s | FileCheck %s +; RUN: llc --mtriple=loongarch64 < %s | FileCheck %s +; RUN: llc --mtriple=loongarch32 --no-integrated-as < %s | FileCheck %s +; RUN: llc --mtriple=loongarch64 --no-integrated-as < %s | FileCheck %s + +;; This regression test is intended to prevent the interface +;; (getOrCreateSymbol()) from being used by the AsmParser to create +;; blockaddress symbols. Otherwise incorrect symbols will be created: +;; `.Ltmp0` -> `.Ltmp00`. + +define void @operand_block_address() nounwind { +; CHECK-LABEL: operand_block_address: +; CHECK: # %bb.0: +; CHECK-NEXT: #APP +; CHECK-NEXT: b .Ltmp0 +; CHECK-NEXT: #NO_APP +; CHECK-NEXT: .Ltmp0: # Block address taken +; CHECK-NEXT: # %bb.1: # %bb +; CHECK-NEXT: ret + call void asm sideeffect "b $0", "i"(i8* blockaddress(@operand_block_address, %bb)) + br label %bb +bb: + ret void +}