diff options
-rw-r--r-- | llvm/lib/Target/AArch64/AArch64RegisterInfo.td | 10 | ||||
-rw-r--r-- | llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp | 4 | ||||
-rw-r--r-- | llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll | 17 |
3 files changed, 25 insertions, 6 deletions
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td index fd1f4e40d62..32039d2caf0 100644 --- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.td +++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.td @@ -653,10 +653,12 @@ def FPR128Op : RegisterOperand<FPR128, "printOperand"> { // ARMv8.1a atomic CASP register operands -def WSeqPairs : RegisterTuples<[sube32, subo32], - [(rotl GPR32, 0), (rotl GPR32, 1)]>; -def XSeqPairs : RegisterTuples<[sube64, subo64], - [(rotl GPR64, 0), (rotl GPR64, 1)]>; +def WSeqPairs : RegisterTuples<[sube32, subo32], + [(decimate (rotl GPR32, 0), 2), + (decimate (rotl GPR32, 1), 2)]>; +def XSeqPairs : RegisterTuples<[sube64, subo64], + [(decimate (rotl GPR64, 0), 2), + (decimate (rotl GPR64, 1), 2)]>; def WSeqPairsClass : RegisterClass<"AArch64", [untyped], 32, (add WSeqPairs)>{ diff --git a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp index 6726c5e7a03..dc1cf368f8e 100644 --- a/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp +++ b/llvm/lib/Target/AArch64/Disassembler/AArch64Disassembler.cpp @@ -1778,8 +1778,8 @@ static DecodeStatus DecodeGPRSeqPairsClassRegisterClass(MCInst &Inst, if (RegNo & 0x1) return Fail; - unsigned Register = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo); - Inst.addOperand(MCOperand::createReg(Register)); + unsigned Reg = AArch64MCRegisterClasses[RegClassID].getRegister(RegNo / 2); + Inst.addOperand(MCOperand::createReg(Reg)); return Success; } diff --git a/llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll b/llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll new file mode 100644 index 00000000000..9c6d8cc2053 --- /dev/null +++ b/llvm/test/CodeGen/AArch64/cmpxchg-lse-even-regs.ll @@ -0,0 +1,17 @@ +; RUN: llc -mtriple arm64-apple-ios -mattr=+lse %s -o - | FileCheck %s + +; Only "even,even+1" pairs are valid for CASP instructions. Make sure LLVM +; doesn't allocate odd ones and that it can copy them around properly. N.b. we +; don't actually check that they're sequential because FileCheck can't; odd/even +; will have to be good enough. +define void @test_atomic_cmpxchg_i128_register_shuffling(i128* %addr, i128 %desired, i128 %new) nounwind { +; CHECK-LABEL: test_atomic_cmpxchg_i128_register_shuffling: +; CHECK-DAG: mov [[DESIRED_LO:x[0-9]*[02468]]], x1 +; CHECK-DAG: mov [[DESIRED_HI:x[0-9]*[13579]]], x2 +; CHECK-DAG: mov [[NEW_LO:x[0-9]*[02468]]], x3 +; CHECK-DAG: mov [[NEW_HI:x[0-9]*[13579]]], x4 +; CHECK: caspal [[DESIRED_LO]], [[DESIRED_HI]], [[NEW_LO]], [[NEW_HI]], [x0] + + %res = cmpxchg i128* %addr, i128 %desired, i128 %new seq_cst seq_cst + ret void +} |