From 71025a2f3e113dbc90c8c303277695809c4ae466 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 6 Feb 2019 15:07:59 +0000 Subject: [PATCH] AArch64: annotate atomics with dropped acquire semantics when printing. A quirk of the v8.1a spec is that when the writeback regiser for an atomic read-modify-write instruction is wzr/xzr, the instruction no longer enforces acquire ordering. However, it's still written with the misleading 'a' mnemonic. So this adds an annotation when disassembling such instructions, mentioning the change. llvm-svn: 353303 --- .../AArch64DeadRegisterDefinitionsPass.cpp | 64 +----- .../InstPrinter/AArch64InstPrinter.cpp | 5 + .../Target/AArch64/Utils/AArch64BaseInfo.h | 43 ++++ llvm/test/MC/AArch64/atomic-acquire-comment.s | 190 ++++++++++++++++++ 4 files changed, 240 insertions(+), 62 deletions(-) create mode 100644 llvm/test/MC/AArch64/atomic-acquire-comment.s diff --git a/llvm/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp b/llvm/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp index ad530d1db778..c0888badb234 100644 --- a/llvm/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp +++ b/llvm/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp @@ -54,8 +54,6 @@ public: AU.setPreservesCFG(); MachineFunctionPass::getAnalysisUsage(AU); } - - bool shouldSkip(const MachineInstr &MI, const MachineFunction &MF) const; }; char AArch64DeadRegisterDefinitions::ID = 0; } // end anonymous namespace @@ -70,63 +68,6 @@ static bool usesFrameIndex(const MachineInstr &MI) { return false; } -bool -AArch64DeadRegisterDefinitions::shouldSkip(const MachineInstr &MI, - const MachineFunction &MF) const { - if (!MF.getSubtarget().hasLSE()) - return false; - -#define CASE_AARCH64_ATOMIC_(PREFIX) \ - case AArch64::PREFIX##X: \ - case AArch64::PREFIX##W: \ - case AArch64::PREFIX##H: \ - case AArch64::PREFIX##B - - for (const MachineMemOperand *MMO : MI.memoperands()) { - if (MMO->isAtomic()) { - unsigned Opcode = MI.getOpcode(); - switch (Opcode) { - default: - return false; - break; - - CASE_AARCH64_ATOMIC_(LDADDA): - CASE_AARCH64_ATOMIC_(LDADDAL): - - CASE_AARCH64_ATOMIC_(LDCLRA): - CASE_AARCH64_ATOMIC_(LDCLRAL): - - CASE_AARCH64_ATOMIC_(LDEORA): - CASE_AARCH64_ATOMIC_(LDEORAL): - - CASE_AARCH64_ATOMIC_(LDSETA): - CASE_AARCH64_ATOMIC_(LDSETAL): - - CASE_AARCH64_ATOMIC_(LDSMAXA): - CASE_AARCH64_ATOMIC_(LDSMAXAL): - - CASE_AARCH64_ATOMIC_(LDSMINA): - CASE_AARCH64_ATOMIC_(LDSMINAL): - - CASE_AARCH64_ATOMIC_(LDUMAXA): - CASE_AARCH64_ATOMIC_(LDUMAXAL): - - CASE_AARCH64_ATOMIC_(LDUMINA): - CASE_AARCH64_ATOMIC_(LDUMINAL): - - CASE_AARCH64_ATOMIC_(SWPA): - CASE_AARCH64_ATOMIC_(SWPAL): - return true; - break; - } - } - } - -#undef CASE_AARCH64_ATOMIC_ - - return false; -} - void AArch64DeadRegisterDefinitions::processMachineBasicBlock( MachineBasicBlock &MBB) { const MachineFunction &MF = *MBB.getParent(); @@ -147,9 +88,8 @@ void AArch64DeadRegisterDefinitions::processMachineBasicBlock( continue; } - if (shouldSkip(MI, MF)) { - LLVM_DEBUG(dbgs() << " Ignoring, Atomic instruction with acquire " - "semantics using WZR/XZR\n"); + if (atomicBarrierDroppedOnZero(MI.getOpcode())) { + LLVM_DEBUG(dbgs() << " Ignoring, semantics change with xzr/wzr.\n"); continue; } diff --git a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp index ad5c0bf26060..d302da740697 100644 --- a/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp +++ b/llvm/lib/Target/AArch64/InstPrinter/AArch64InstPrinter.cpp @@ -69,6 +69,11 @@ void AArch64InstPrinter::printInst(const MCInst *MI, raw_ostream &O, return; } + if (atomicBarrierDroppedOnZero(Opcode) && + (MI->getOperand(0).getReg() == AArch64::XZR || + MI->getOperand(0).getReg() == AArch64::WZR)) + printAnnotation(O, "acquire semantics dropped since destination is zero"); + // SBFM/UBFM should print to a nicer aliased form if possible. if (Opcode == AArch64::SBFMXri || Opcode == AArch64::SBFMWri || Opcode == AArch64::UBFMXri || Opcode == AArch64::UBFMWri) { diff --git a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h index ef0578373733..e5e2fc2cb0df 100644 --- a/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h +++ b/llvm/lib/Target/AArch64/Utils/AArch64BaseInfo.h @@ -185,6 +185,49 @@ static inline unsigned getDRegFromBReg(unsigned Reg) { return Reg; } +static inline bool atomicBarrierDroppedOnZero(unsigned Opcode) { + switch (Opcode) { + case AArch64::LDADDAB: case AArch64::LDADDAH: + case AArch64::LDADDAW: case AArch64::LDADDAX: + case AArch64::LDADDALB: case AArch64::LDADDALH: + case AArch64::LDADDALW: case AArch64::LDADDALX: + case AArch64::LDCLRAB: case AArch64::LDCLRAH: + case AArch64::LDCLRAW: case AArch64::LDCLRAX: + case AArch64::LDCLRALB: case AArch64::LDCLRALH: + case AArch64::LDCLRALW: case AArch64::LDCLRALX: + case AArch64::LDEORAB: case AArch64::LDEORAH: + case AArch64::LDEORAW: case AArch64::LDEORAX: + case AArch64::LDEORALB: case AArch64::LDEORALH: + case AArch64::LDEORALW: case AArch64::LDEORALX: + case AArch64::LDSETAB: case AArch64::LDSETAH: + case AArch64::LDSETAW: case AArch64::LDSETAX: + case AArch64::LDSETALB: case AArch64::LDSETALH: + case AArch64::LDSETALW: case AArch64::LDSETALX: + case AArch64::LDSMAXAB: case AArch64::LDSMAXAH: + case AArch64::LDSMAXAW: case AArch64::LDSMAXAX: + case AArch64::LDSMAXALB: case AArch64::LDSMAXALH: + case AArch64::LDSMAXALW: case AArch64::LDSMAXALX: + case AArch64::LDSMINAB: case AArch64::LDSMINAH: + case AArch64::LDSMINAW: case AArch64::LDSMINAX: + case AArch64::LDSMINALB: case AArch64::LDSMINALH: + case AArch64::LDSMINALW: case AArch64::LDSMINALX: + case AArch64::LDUMAXAB: case AArch64::LDUMAXAH: + case AArch64::LDUMAXAW: case AArch64::LDUMAXAX: + case AArch64::LDUMAXALB: case AArch64::LDUMAXALH: + case AArch64::LDUMAXALW: case AArch64::LDUMAXALX: + case AArch64::LDUMINAB: case AArch64::LDUMINAH: + case AArch64::LDUMINAW: case AArch64::LDUMINAX: + case AArch64::LDUMINALB: case AArch64::LDUMINALH: + case AArch64::LDUMINALW: case AArch64::LDUMINALX: + case AArch64::SWPAB: case AArch64::SWPAH: + case AArch64::SWPAW: case AArch64::SWPAX: + case AArch64::SWPALB: case AArch64::SWPALH: + case AArch64::SWPALW: case AArch64::SWPALX: + return true; + } + return false; +} + namespace AArch64CC { // The CondCodes constants map directly to the 4-bit encoding of the condition diff --git a/llvm/test/MC/AArch64/atomic-acquire-comment.s b/llvm/test/MC/AArch64/atomic-acquire-comment.s new file mode 100644 index 000000000000..62aadddf0837 --- /dev/null +++ b/llvm/test/MC/AArch64/atomic-acquire-comment.s @@ -0,0 +1,190 @@ +; RUN: llvm-mc -triple aarch64-apple-ios -mattr=+lse %s | FileCheck %s + + ; CHECK: ldaddab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldaddah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldadda w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldadda x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldaddab w3, wzr, [x5] + ldaddah w5, wzr, [x0] + ldadda w7, wzr, [x5] + ldadda x9, xzr, [sp] + + ; CHECK: ldaddalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldaddalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldaddal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldaddal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldaddalb w3, wzr, [x5] + ldaddalh w5, wzr, [x0] + ldaddal w7, wzr, [x5] + ldaddal x9, xzr, [sp] + + ; CHECK: ldclrab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldclrah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldclra w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldclra x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldclrab w3, wzr, [x5] + ldclrah w5, wzr, [x0] + ldclra w7, wzr, [x5] + ldclra x9, xzr, [sp] + + ; CHECK: ldclralb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldclralh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldclral w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldclral x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldclralb w3, wzr, [x5] + ldclralh w5, wzr, [x0] + ldclral w7, wzr, [x5] + ldclral x9, xzr, [sp] + + ; CHECK: ldeorab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldeorah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldeora w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldeora x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldeorab w3, wzr, [x5] + ldeorah w5, wzr, [x0] + ldeora w7, wzr, [x5] + ldeora x9, xzr, [sp] + + ; CHECK: ldeoralb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldeoralh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldeoral w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldeoral x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldeoralb w3, wzr, [x5] + ldeoralh w5, wzr, [x0] + ldeoral w7, wzr, [x5] + ldeoral x9, xzr, [sp] + + ; CHECK: ldsetab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsetah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldseta w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldseta x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldsetab w3, wzr, [x5] + ldsetah w5, wzr, [x0] + ldseta w7, wzr, [x5] + ldseta x9, xzr, [sp] + + ; CHECK: ldsetalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsetalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldsetal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsetal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldsetalb w3, wzr, [x5] + ldsetalh w5, wzr, [x0] + ldsetal w7, wzr, [x5] + ldsetal x9, xzr, [sp] + + ; CHECK: ldsmaxab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmaxah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmaxa w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmaxa x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldsmaxab w3, wzr, [x5] + ldsmaxah w5, wzr, [x0] + ldsmaxa w7, wzr, [x5] + ldsmaxa x9, xzr, [sp] + + ; CHECK: ldsmaxalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmaxalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmaxal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmaxal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldsmaxalb w3, wzr, [x5] + ldsmaxalh w5, wzr, [x0] + ldsmaxal w7, wzr, [x5] + ldsmaxal x9, xzr, [sp] + + ; CHECK: ldsminab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsminah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmina w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsmina x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldsminab w3, wzr, [x5] + ldsminah w5, wzr, [x0] + ldsmina w7, wzr, [x5] + ldsmina x9, xzr, [sp] + + ; CHECK: ldsminalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsminalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldsminal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldsminal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldsminalb w3, wzr, [x5] + ldsminalh w5, wzr, [x0] + ldsminal w7, wzr, [x5] + ldsminal x9, xzr, [sp] + + ; CHECK: ldumaxab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldumaxah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldumaxa w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldumaxa x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldumaxab w3, wzr, [x5] + ldumaxah w5, wzr, [x0] + ldumaxa w7, wzr, [x5] + ldumaxa x9, xzr, [sp] + + ; CHECK: ldumaxalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldumaxalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldumaxal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldumaxal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + ldumaxalb w3, wzr, [x5] + ldumaxalh w5, wzr, [x0] + ldumaxal w7, wzr, [x5] + ldumaxal x9, xzr, [sp] + + ; CHECK: lduminab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: lduminah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: ldumina w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: ldumina x9, xzr, [sp] ; acquire semantics dropped since destination is zero + lduminab w3, wzr, [x5] + lduminah w5, wzr, [x0] + ldumina w7, wzr, [x5] + ldumina x9, xzr, [sp] + + ; CHECK: lduminalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: lduminalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: lduminal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: lduminal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + lduminalb w3, wzr, [x5] + lduminalh w5, wzr, [x0] + lduminal w7, wzr, [x5] + lduminal x9, xzr, [sp] + + ; CHECK: swpab w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: swpah w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: swpa w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: swpa x9, xzr, [sp] ; acquire semantics dropped since destination is zero + swpab w3, wzr, [x5] + swpah w5, wzr, [x0] + swpa w7, wzr, [x5] + swpa x9, xzr, [sp] + + ; CHECK: swpalb w3, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: swpalh w5, wzr, [x0] ; acquire semantics dropped since destination is zero + ; CHECK: swpal w7, wzr, [x5] ; acquire semantics dropped since destination is zero + ; CHECK: swpal x9, xzr, [sp] ; acquire semantics dropped since destination is zero + swpalb w3, wzr, [x5] + swpalh w5, wzr, [x0] + swpal w7, wzr, [x5] + swpal x9, xzr, [sp] + + ; CHECK: ldaddal xzr, x3, [x0]{{$}} + ; CHECK: ldeora wzr, w7, [x5]{{$}} + ; CHECK: ldsminb w5, w9, [sp]{{$}} + ldaddal xzr, x3, [x0] + ldeora wzr, w7, [x5] + ldsminb w5, w9, [sp] + + ; CAS instructions aren't affected. + + ; CHECK: casab w3, wzr, [x5]{{$}} + ; CHECK: casah w5, wzr, [x0]{{$}} + ; CHECK: casa w7, wzr, [x5]{{$}} + ; CHECK: casa x9, xzr, [sp]{{$}} + casab w3, wzr, [x5] + casah w5, wzr, [x0] + casa w7, wzr, [x5] + casa x9, xzr, [sp] + + ; CHECK: casalb w3, wzr, [x5]{{$}} + ; CHECK: casalh w5, wzr, [x0]{{$}} + ; CHECK: casal w7, wzr, [x5]{{$}} + ; CHECK: casal x9, xzr, [sp]{{$}} + casalb w3, wzr, [x5] + casalh w5, wzr, [x0] + casal w7, wzr, [x5] + casal x9, xzr, [sp]