From 31cadd791aae37b30d5daabbf680c4970a3fba68 Mon Sep 17 00:00:00 2001 From: Tim Northover Date: Wed, 13 Apr 2016 16:25:39 +0000 Subject: [PATCH] AArch64: don't create instructions that write to xzr/wzr twice. These are unpredictable even on AArch64. Patch by Yichao Yu. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@266206 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp | 8 ++++++++ test/CodeGen/AArch64/arm64-atomic-128.ll | 6 +++--- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp b/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp index fe850ecd140..54825c427a6 100644 --- a/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp +++ b/lib/Target/AArch64/AArch64DeadRegisterDefinitionsPass.cpp @@ -93,6 +93,12 @@ bool AArch64DeadRegisterDefinitions::processMachineBasicBlock( DEBUG(dbgs() << " Ignoring, operand is frame index\n"); continue; } + if (MI.definesRegister(AArch64::XZR) || MI.definesRegister(AArch64::WZR)) { + // It is not allowed to write to the same register (not even the zero + // register) twice in a single instruction. + DEBUG(dbgs() << " Ignoring, XZR or WZR already used by the instruction\n"); + continue; + } for (int i = 0, e = MI.getDesc().getNumDefs(); i != e; ++i) { MachineOperand &MO = MI.getOperand(i); if (MO.isReg() && MO.isDead() && MO.isDef()) { @@ -128,6 +134,8 @@ bool AArch64DeadRegisterDefinitions::processMachineBasicBlock( MO.setReg(NewReg); DEBUG(MI.print(dbgs())); ++NumDeadDefsReplaced; + // Only replace one dead register, see check for zero register above. + break; } } } diff --git a/test/CodeGen/AArch64/arm64-atomic-128.ll b/test/CodeGen/AArch64/arm64-atomic-128.ll index 44c24c51f0d..d7188f31c56 100644 --- a/test/CodeGen/AArch64/arm64-atomic-128.ll +++ b/test/CodeGen/AArch64/arm64-atomic-128.ll @@ -190,7 +190,7 @@ define void @atomic_store_seq_cst(i128 %in, i128* %p) { ; CHECK-LABEL: atomic_store_seq_cst: ; CHECK-NOT: dmb ; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]: -; CHECK: ldaxp xzr, xzr, [x2] +; CHECK: ldaxp xzr, [[IGNORED:x[0-9]+]], [x2] ; CHECK: stlxp [[SUCCESS:w[0-9]+]], x0, x1, [x2] ; CHECK: cbnz [[SUCCESS]], [[LABEL]] ; CHECK-NOT: dmb @@ -202,7 +202,7 @@ define void @atomic_store_release(i128 %in, i128* %p) { ; CHECK-LABEL: atomic_store_release: ; CHECK-NOT: dmb ; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]: -; CHECK: ldxp xzr, xzr, [x2] +; CHECK: ldxp xzr, [[IGNORED:x[0-9]+]], [x2] ; CHECK: stlxp [[SUCCESS:w[0-9]+]], x0, x1, [x2] ; CHECK: cbnz [[SUCCESS]], [[LABEL]] ; CHECK-NOT: dmb @@ -214,7 +214,7 @@ define void @atomic_store_relaxed(i128 %in, i128* %p) { ; CHECK-LABEL: atomic_store_relaxed: ; CHECK-NOT: dmb ; CHECK: [[LABEL:.?LBB[0-9]+_[0-9]+]]: -; CHECK: ldxp xzr, xzr, [x2] +; CHECK: ldxp xzr, [[IGNORED:x[0-9]+]], [x2] ; CHECK: stxp [[SUCCESS:w[0-9]+]], x0, x1, [x2] ; CHECK: cbnz [[SUCCESS]], [[LABEL]] ; CHECK-NOT: dmb