From b534db940ca736eb33d74ec08a39b9f1b2e34ac9 Mon Sep 17 00:00:00 2001 From: Zi Xuan Wu Date: Fri, 28 Dec 2018 02:12:55 +0000 Subject: [PATCH] [PowerPC] Fix assert from machine verify pass that atomic pseudo expanding causes mismatched register class For atomic value operand which less than 4 bytes need to be masked. And the related operation to calculate the newvalue can be done in 32 bit gprc. So just use gprc for mask and value calculation. Differential Revision: https://reviews.llvm.org/D56077 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@350113 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCISelLowering.cpp | 81 ++++++++++++--------- test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll | 4 +- test/CodeGen/PowerPC/atomic-2.ll | 8 +- test/CodeGen/PowerPC/atomic-minmax.ll | 18 ++--- test/CodeGen/PowerPC/atomics.ll | 5 +- 5 files changed, 63 insertions(+), 53 deletions(-) diff --git a/lib/Target/PowerPC/PPCISelLowering.cpp b/lib/Target/PowerPC/PPCISelLowering.cpp index fed73639ce6..d6f5d9e35aa 100644 --- a/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/lib/Target/PowerPC/PPCISelLowering.cpp @@ -9927,20 +9927,24 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, MachineRegisterInfo &RegInfo = F->getRegInfo(); const TargetRegisterClass *RC = is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass; + const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; + unsigned PtrReg = RegInfo.createVirtualRegister(RC); - unsigned Shift1Reg = RegInfo.createVirtualRegister(RC); + unsigned Shift1Reg = RegInfo.createVirtualRegister(GPRC); unsigned ShiftReg = - isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(RC); - unsigned Incr2Reg = RegInfo.createVirtualRegister(RC); - unsigned MaskReg = RegInfo.createVirtualRegister(RC); - unsigned Mask2Reg = RegInfo.createVirtualRegister(RC); - unsigned Mask3Reg = RegInfo.createVirtualRegister(RC); - unsigned Tmp2Reg = RegInfo.createVirtualRegister(RC); - unsigned Tmp3Reg = RegInfo.createVirtualRegister(RC); - unsigned Tmp4Reg = RegInfo.createVirtualRegister(RC); - unsigned TmpDestReg = RegInfo.createVirtualRegister(RC); + isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC); + unsigned Incr2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned MaskReg = RegInfo.createVirtualRegister(GPRC); + unsigned Mask2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Mask3Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Tmp2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Tmp3Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Tmp4Reg = RegInfo.createVirtualRegister(GPRC); + unsigned TmpDestReg = RegInfo.createVirtualRegister(GPRC); unsigned Ptr1Reg; - unsigned TmpReg = (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(RC); + unsigned TmpReg = (!BinOpcode) ? Incr2Reg : RegInfo.createVirtualRegister(GPRC); + + // thisMBB: // ... @@ -9973,10 +9977,12 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, } else { Ptr1Reg = ptrB; } - BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg) + // We need use 32-bit subregister to avoid mismatch register class in 64-bit mode. + BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg) + .addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0) .addImm(3).addImm(27).addImm(is8bit ? 28 : 27); if (!isLittleEndian) - BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) + BuildMI(BB, dl, TII->get(PPC::XORI), ShiftReg) .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); if (is64bit) BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg) @@ -10001,23 +10007,23 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, if (BinOpcode) BuildMI(BB, dl, TII->get(BinOpcode), TmpReg) .addReg(Incr2Reg).addReg(TmpDestReg); - BuildMI(BB, dl, TII->get(is64bit ? PPC::ANDC8 : PPC::ANDC), Tmp2Reg) + BuildMI(BB, dl, TII->get(PPC::ANDC), Tmp2Reg) .addReg(TmpDestReg).addReg(MaskReg); - BuildMI(BB, dl, TII->get(is64bit ? PPC::AND8 : PPC::AND), Tmp3Reg) + BuildMI(BB, dl, TII->get(PPC::AND), Tmp3Reg) .addReg(TmpReg).addReg(MaskReg); if (CmpOpcode) { // For unsigned comparisons, we can directly compare the shifted values. // For signed comparisons we shift and sign extend. - unsigned SReg = RegInfo.createVirtualRegister(RC); - BuildMI(BB, dl, TII->get(is64bit ? PPC::AND8 : PPC::AND), SReg) + unsigned SReg = RegInfo.createVirtualRegister(GPRC); + BuildMI(BB, dl, TII->get(PPC::AND), SReg) .addReg(TmpDestReg).addReg(MaskReg); unsigned ValueReg = SReg; unsigned CmpReg = Incr2Reg; if (CmpOpcode == PPC::CMPW) { - ValueReg = RegInfo.createVirtualRegister(RC); + ValueReg = RegInfo.createVirtualRegister(GPRC); BuildMI(BB, dl, TII->get(PPC::SRW), ValueReg) .addReg(SReg).addReg(ShiftReg); - unsigned ValueSReg = RegInfo.createVirtualRegister(RC); + unsigned ValueSReg = RegInfo.createVirtualRegister(GPRC); BuildMI(BB, dl, TII->get(is8bit ? PPC::EXTSB : PPC::EXTSH), ValueSReg) .addReg(ValueReg); ValueReg = ValueSReg; @@ -10031,7 +10037,7 @@ PPCTargetLowering::EmitPartwordAtomicBinary(MachineInstr &MI, BB->addSuccessor(exitMBB); BB = loop2MBB; } - BuildMI(BB, dl, TII->get(is64bit ? PPC::OR8 : PPC::OR), Tmp4Reg) + BuildMI(BB, dl, TII->get(PPC::OR), Tmp4Reg) .addReg(Tmp3Reg).addReg(Tmp2Reg); BuildMI(BB, dl, TII->get(PPC::STWCX)) .addReg(Tmp4Reg).addReg(ZeroReg).addReg(PtrReg); @@ -10704,22 +10710,24 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineRegisterInfo &RegInfo = F->getRegInfo(); const TargetRegisterClass *RC = is64bit ? &PPC::G8RCRegClass : &PPC::GPRCRegClass; + const TargetRegisterClass *GPRC = &PPC::GPRCRegClass; + unsigned PtrReg = RegInfo.createVirtualRegister(RC); - unsigned Shift1Reg = RegInfo.createVirtualRegister(RC); + unsigned Shift1Reg = RegInfo.createVirtualRegister(GPRC); unsigned ShiftReg = - isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(RC); - unsigned NewVal2Reg = RegInfo.createVirtualRegister(RC); - unsigned NewVal3Reg = RegInfo.createVirtualRegister(RC); - unsigned OldVal2Reg = RegInfo.createVirtualRegister(RC); - unsigned OldVal3Reg = RegInfo.createVirtualRegister(RC); - unsigned MaskReg = RegInfo.createVirtualRegister(RC); - unsigned Mask2Reg = RegInfo.createVirtualRegister(RC); - unsigned Mask3Reg = RegInfo.createVirtualRegister(RC); - unsigned Tmp2Reg = RegInfo.createVirtualRegister(RC); - unsigned Tmp4Reg = RegInfo.createVirtualRegister(RC); - unsigned TmpDestReg = RegInfo.createVirtualRegister(RC); + isLittleEndian ? Shift1Reg : RegInfo.createVirtualRegister(GPRC); + unsigned NewVal2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned NewVal3Reg = RegInfo.createVirtualRegister(GPRC); + unsigned OldVal2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned OldVal3Reg = RegInfo.createVirtualRegister(GPRC); + unsigned MaskReg = RegInfo.createVirtualRegister(GPRC); + unsigned Mask2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Mask3Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Tmp2Reg = RegInfo.createVirtualRegister(GPRC); + unsigned Tmp4Reg = RegInfo.createVirtualRegister(GPRC); + unsigned TmpDestReg = RegInfo.createVirtualRegister(GPRC); unsigned Ptr1Reg; - unsigned TmpReg = RegInfo.createVirtualRegister(RC); + unsigned TmpReg = RegInfo.createVirtualRegister(GPRC); unsigned ZeroReg = is64bit ? PPC::ZERO8 : PPC::ZERO; // thisMBB: // ... @@ -10760,10 +10768,13 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, } else { Ptr1Reg = ptrB; } - BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg).addReg(Ptr1Reg) + + // We need use 32-bit subregister to avoid mismatch register class in 64-bit mode. + BuildMI(BB, dl, TII->get(PPC::RLWINM), Shift1Reg) + .addReg(Ptr1Reg, 0, is64bit ? PPC::sub_32 : 0) .addImm(3).addImm(27).addImm(is8bit ? 28 : 27); if (!isLittleEndian) - BuildMI(BB, dl, TII->get(is64bit ? PPC::XORI8 : PPC::XORI), ShiftReg) + BuildMI(BB, dl, TII->get(PPC::XORI), ShiftReg) .addReg(Shift1Reg).addImm(is8bit ? 24 : 16); if (is64bit) BuildMI(BB, dl, TII->get(PPC::RLDICR), PtrReg) diff --git a/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll b/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll index f249dd868c9..aa0e1fc1f39 100644 --- a/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll +++ b/test/CodeGen/PowerPC/PR35812-neg-cmpxchg.ll @@ -2,7 +2,7 @@ ; Make sure that a negative value for the compare-and-swap is zero extended ; from i8/i16 to i32 since it will be compared for equality. ; RUN: llc -mtriple=powerpc64le-linux-gnu -verify-machineinstrs < %s | FileCheck %s -; RUN: llc -mtriple=powerpc64le-linux-gnu -mcpu=pwr7 < %s | FileCheck %s --check-prefix=CHECK-P7 +; RUN: llc -mtriple=powerpc64le-linux-gnu -mcpu=pwr7 -verify-machineinstrs < %s | FileCheck %s --check-prefix=CHECK-P7 @str = private unnamed_addr constant [46 x i8] c"FAILED: __atomic_compare_exchange_n() failed.\00" @str.1 = private unnamed_addr constant [59 x i8] c"FAILED: __atomic_compare_exchange_n() set the wrong value.\00" @@ -50,7 +50,7 @@ define signext i32 @main() { ; CHECK-P7: .LBB0_1: # %L.entry ; CHECK-P7: lwarx 9, 0, 4 ; CHECK-P7: and 6, 9, 5 -; CHECK-P7: cmpw 0, 6, 8 +; CHECK-P7: cmpw 6, 8 ; CHECK-P7: bne 0, .LBB0_3 ; CHECK-P7: andc 9, 9, 5 ; CHECK-P7: or 9, 9, 7 diff --git a/test/CodeGen/PowerPC/atomic-2.ll b/test/CodeGen/PowerPC/atomic-2.ll index c1fbb435020..29d16ef82d2 100644 --- a/test/CodeGen/PowerPC/atomic-2.ll +++ b/test/CodeGen/PowerPC/atomic-2.ll @@ -1,7 +1,7 @@ -; RUN: llc < %s -ppc-asm-full-reg-names -mtriple=ppc64-- | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE -; RUN: llc < %s -ppc-asm-full-reg-names -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE -; RUN: llc < %s -ppc-asm-full-reg-names -mtriple=ppc64-- -mcpu=pwr7 | FileCheck %s -; RUN: llc < %s -ppc-asm-full-reg-names -mtriple=ppc64-- -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-P8U +; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=ppc64-- | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-BE +; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=powerpc64le-unknown-linux-gnu | FileCheck %s -check-prefix=CHECK -check-prefix=CHECK-LE +; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=ppc64-- -mcpu=pwr7 | FileCheck %s +; RUN: llc -verify-machineinstrs < %s -ppc-asm-full-reg-names -mtriple=ppc64-- -mcpu=pwr8 | FileCheck %s -check-prefix=CHECK-P8U define i64 @exchange_and_add(i64* %mem, i64 %val) nounwind { ; CHECK-LABEL: exchange_and_add: diff --git a/test/CodeGen/PowerPC/atomic-minmax.ll b/test/CodeGen/PowerPC/atomic-minmax.ll index 5b9a1533189..f7369f30a38 100644 --- a/test/CodeGen/PowerPC/atomic-minmax.ll +++ b/test/CodeGen/PowerPC/atomic-minmax.ll @@ -1,4 +1,4 @@ -; RUN: llc < %s | FileCheck %s +; RUN: llc -verify-machineinstrs < %s | FileCheck %s target datalayout = "E-m:e-i64:64-n32:64" target triple = "powerpc64-unknown-linux-gnu" @@ -244,7 +244,7 @@ entry: ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] ; CHECK: extsh [[SESMOLDV:[0-9]+]], [[SMOLDV]] -; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: cmpw 4, [[SESMOLDV]] ; CHECK: bgelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -271,7 +271,7 @@ entry: ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] ; CHECK: extsh [[SESMOLDV:[0-9]+]], [[SMOLDV]] -; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: cmpw 4, [[SESMOLDV]] ; CHECK: blelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -296,7 +296,7 @@ entry: ; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] ; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] -; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: cmplw 4, [[MOLDV]] ; CHECK: bgelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -321,7 +321,7 @@ entry: ; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] ; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] -; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: cmplw 4, [[MOLDV]] ; CHECK: blelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -347,7 +347,7 @@ entry: ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] ; CHECK: extsb [[SESMOLDV:[0-9]+]], [[SMOLDV]] -; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: cmpw 4, [[SESMOLDV]] ; CHECK: bgelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -373,7 +373,7 @@ entry: ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: srw [[SMOLDV:[0-9]+]], [[MOLDV]], [[SA]] ; CHECK: extsb [[SESMOLDV:[0-9]+]], [[SMOLDV]] -; CHECK: cmpw 0, 4, [[SESMOLDV]] +; CHECK: cmpw 4, [[SESMOLDV]] ; CHECK: blelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -397,7 +397,7 @@ entry: ; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] ; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] -; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: cmplw 4, [[MOLDV]] ; CHECK: bgelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] @@ -421,7 +421,7 @@ entry: ; CHECK-DAG: and [[SMV:[0-9]+]], [[SV]], [[M]] ; CHECK: lwarx [[OLDV:[0-9]+]], 0, 3 ; CHECK: and [[MOLDV:[0-9]+]], [[OLDV]], [[M]] -; CHECK: cmplw 0, 4, [[MOLDV]] +; CHECK: cmplw 4, [[MOLDV]] ; CHECK: blelr 0 ; CHECK: andc [[NOLDV:[0-9]+]], [[OLDV]], [[M]] ; CHECK: or [[NEWV:[0-9]+]], [[SMV]], [[NOLDV]] diff --git a/test/CodeGen/PowerPC/atomics.ll b/test/CodeGen/PowerPC/atomics.ll index 1abc9dc48c9..c964218cb60 100644 --- a/test/CodeGen/PowerPC/atomics.ll +++ b/test/CodeGen/PowerPC/atomics.ll @@ -1,7 +1,6 @@ -; RUN: llc < %s -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC32 -; FIXME: -verify-machineinstrs currently fail on ppc64 (mismatched register/instruction). +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc-unknown-linux-gnu -verify-machineinstrs -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC32 ; This is already checked for in Atomics-64.ll -; RUN: llc < %s -mtriple=powerpc64-unknown-linux-gnu -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC64 +; RUN: llc -verify-machineinstrs < %s -mtriple=powerpc64-unknown-linux-gnu -ppc-asm-full-reg-names | FileCheck %s --check-prefix=CHECK --check-prefix=PPC64 ; FIXME: we don't currently check for the operations themselves with CHECK-NEXT, ; because they are implemented in a very messy way with lwarx/stwcx. -- 2.50.1