From aec5010b2703cf394363930e129b80ea8df6852e Mon Sep 17 00:00:00 2001 From: Keno Fischer Date: Wed, 1 Jun 2016 20:31:07 +0000 Subject: [PATCH] [PPC64] Fix SUBFC8 Defs list Fix PR27943 "Bad machine code: Using an undefined physical register". SUBFC8 implicitly defines the CR0 register, but this was omitted in the instruction definition. Patch by Jameson Nash Reviewers: hfinkel Differential Revision: http://reviews.llvm.org/D20802 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@271425 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/PowerPC/PPCInstr64Bit.td | 4 +- lib/Target/PowerPC/PPCInstrInfo.cpp | 2 + test/CodeGen/PowerPC/opt-sub-inst-cr0-live.mir | 143 +++++++++++++++++++++++++ 3 files changed, 147 insertions(+), 2 deletions(-) create mode 100644 test/CodeGen/PowerPC/opt-sub-inst-cr0-live.mir diff --git a/lib/Target/PowerPC/PPCInstr64Bit.td b/lib/Target/PowerPC/PPCInstr64Bit.td index 52af29356d1..e7eb8a16180 100644 --- a/lib/Target/PowerPC/PPCInstr64Bit.td +++ b/lib/Target/PowerPC/PPCInstr64Bit.td @@ -514,11 +514,11 @@ let Defs = [CARRY] in { def SUBFIC8: DForm_2< 8, (outs g8rc:$rD), (ins g8rc:$rA, s16imm64:$imm), "subfic $rD, $rA, $imm", IIC_IntGeneral, [(set i64:$rD, (subc imm64SExt16:$imm, i64:$rA))]>; -defm SUBFC8 : XOForm_1r<31, 8, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB), +} +defm SUBFC8 : XOForm_1rc<31, 8, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB), "subfc", "$rT, $rA, $rB", IIC_IntGeneral, [(set i64:$rT, (subc i64:$rB, i64:$rA))]>, PPC970_DGroup_Cracked; -} defm SUBF8 : XOForm_1r<31, 40, 0, (outs g8rc:$rT), (ins g8rc:$rA, g8rc:$rB), "subf", "$rT, $rA, $rB", IIC_IntGeneral, [(set i64:$rT, (sub i64:$rB, i64:$rA))]>; diff --git a/lib/Target/PowerPC/PPCInstrInfo.cpp b/lib/Target/PowerPC/PPCInstrInfo.cpp index 313ab8846ad..9d8e29c462c 100644 --- a/lib/Target/PowerPC/PPCInstrInfo.cpp +++ b/lib/Target/PowerPC/PPCInstrInfo.cpp @@ -1795,6 +1795,8 @@ bool PPCInstrInfo::optimizeCompareInstr(MachineInstr *CmpInstr, MI->addOperand(*MI->getParent()->getParent(), MachineOperand::CreateReg(*ImpUses, false, true)); } + assert(MI->definesRegister(PPC::CR0) && + "Record-form instruction does not define cr0?"); // Modify the condition code of operands in OperandsToUpdate. // Since we have SUB(r1, r2) and CMP(r2, r1), the condition code needs to diff --git a/test/CodeGen/PowerPC/opt-sub-inst-cr0-live.mir b/test/CodeGen/PowerPC/opt-sub-inst-cr0-live.mir new file mode 100644 index 00000000000..2b14babe6f0 --- /dev/null +++ b/test/CodeGen/PowerPC/opt-sub-inst-cr0-live.mir @@ -0,0 +1,143 @@ +# RUN: llc -start-after=machine-sink -stop-after=peephole-opts -mtriple=powerpc64-unknown-linux-gnu -o /dev/null %s 2>&1 | FileCheck %s + +--- | + ; ModuleID = '' + source_filename = "" + target datalayout = "E-m:e-i64:64-n32:64" + target triple = "powerpc64-unknown-linux-gnu" + + ; Function Attrs: nounwind readnone + declare i128 @llvm.cttz.i128(i128, i1) #0 + + define void @fn1(i128, i128, i1) { + top: + br label %loop + + loop: ; preds = %loop, %top + %v = phi i128 [ %3, %loop ], [ %0, %top ] + %u = phi i128 [ %3, %loop ], [ %1, %top ] + %s = sub i128 %v, %u + %3 = call i128 @llvm.cttz.i128(i128 %s, i1 false) + br label %loop + } + + ; Function Attrs: nounwind + declare void @llvm.stackprotector(i8*, i8**) #1 + + attributes #0 = { nounwind readnone } + attributes #1 = { nounwind } + +... +--- +name: fn1 +alignment: 2 +exposesReturnsTwice: false +hasInlineAsm: false +allVRegsAllocated: false +isSSA: true +tracksRegLiveness: true +tracksSubRegLiveness: false +registers: + - { id: 0, class: g8rc } + - { id: 1, class: g8rc } + - { id: 2, class: g8rc } + - { id: 3, class: g8rc } + - { id: 4, class: g8rc } + - { id: 5, class: g8rc } + - { id: 6, class: g8rc } + - { id: 7, class: g8rc } + - { id: 8, class: g8rc } + - { id: 9, class: g8rc } + - { id: 10, class: g8rc } + - { id: 11, class: g8rc } + - { id: 12, class: g8rc } + - { id: 13, class: g8rc } + - { id: 14, class: g8rc } + - { id: 15, class: g8rc_and_g8rc_nox0 } + - { id: 16, class: g8rc_and_g8rc_nox0 } + - { id: 17, class: g8rc } + - { id: 18, class: g8rc } + - { id: 19, class: g8rc } + - { id: 20, class: g8rc } + - { id: 21, class: g8rc } + - { id: 22, class: g8rc } + - { id: 23, class: g8rc } + - { id: 24, class: g8rc } + - { id: 25, class: crrc } + - { id: 26, class: g8rc_and_g8rc_nox0 } + - { id: 27, class: g8rc_and_g8rc_nox0 } +liveins: + - { reg: '%x3', virtual-reg: '%6' } + - { reg: '%x4', virtual-reg: '%7' } + - { reg: '%x5', virtual-reg: '%8' } + - { reg: '%x6', virtual-reg: '%9' } +frameInfo: + isFrameAddressTaken: false + isReturnAddressTaken: false + hasStackMap: false + hasPatchPoint: false + stackSize: 0 + offsetAdjustment: 0 + maxAlignment: 0 + adjustsStack: false + hasCalls: false + maxCallFrameSize: 0 + hasOpaqueSPAdjustment: false + hasVAStart: false + hasMustTailInVarArgFunc: false +body: | + bb.0.top: + successors: %bb.1.loop + liveins: %x3, %x4, %x5, %x6 + + %9 = COPY %x6 + %8 = COPY %x5 + %7 = COPY %x4 + %6 = COPY %x3 + %14 = COPY %9 + %13 = COPY %8 + %12 = COPY %7 + %11 = COPY %6 + %21 = LI8 128 + %23 = LI8 64 + + bb.1.loop: + successors: %bb.2.loop, %bb.4 + + %0 = PHI %11, %bb.0.top, %4, %bb.3.loop + %1 = PHI %12, %bb.0.top, %5, %bb.3.loop + %2 = PHI %13, %bb.0.top, %4, %bb.3.loop + %3 = PHI %14, %bb.0.top, %5, %bb.3.loop + %15 = SUBFC8 %3, %1, implicit-def %carry + %16 = SUBFE8 %2, %0, implicit-def dead %carry, implicit %carry + %17 = ADDI8 %16, -1 + %18 = ADDI8 %15, -1 + %19 = ANDC8 killed %17, %16 + %20 = ANDC8 killed %18, %15 + %22 = CNTLZD killed %19 + %24 = CNTLZD killed %20 + %25 = CMPLDI %15, 0 + BCC 76, %25, %bb.2.loop + ; CHECK: SUBFC8o %3, %1, implicit-def %carry, implicit-def %cr0 + ; CHECK: COPY killed %cr0 + ; CHECK: BCC + + bb.4: + successors: %bb.3.loop + + %27 = SUBF8 %24, %23 + B %bb.3.loop + + bb.2.loop: + successors: %bb.3.loop + + %26 = SUBF8 %22, %21 + + bb.3.loop: + successors: %bb.1.loop + + %5 = PHI %26, %bb.2.loop, %27, %bb.4 + %4 = LI8 0 + B %bb.1.loop + +... -- 2.11.0