From 157b073fa54eb7ca30774726754fd4859c236177 Mon Sep 17 00:00:00 2001 From: Jinsong Ji Date: Thu, 27 Jun 2019 14:11:31 +0000 Subject: [PATCH] [PowerPC][HTM] Fix disassembling buffer overflow for tabortdc and others This was reported in https://bugs.llvm.org/show_bug.cgi?id=41751 llvm-mc aborted when disassembling tabortdc. This patch try to clean up TM related DAGs. * Fixes the problem by remove explicit output of cr0, and put it as implicit def. * Update int_ppc_tbegin pattern to accommodate the implicit def of cr0. * Update the TCHECK operand and int_ppc_tcheck accordingly. * Add some builtin test and disassembly tests. * Remove unused CRRC0/crrc0 Differential Revision: https://reviews.llvm.org/D61935 llvm-svn: 364544 --- .../PowerPC/Disassembler/PPCDisassembler.cpp | 6 --- llvm/lib/Target/PowerPC/PPCISelLowering.cpp | 11 +++++- llvm/lib/Target/PowerPC/PPCInstrHTM.td | 38 +++++++++---------- llvm/lib/Target/PowerPC/PPCInstrInfo.td | 4 -- llvm/lib/Target/PowerPC/PPCRegisterInfo.td | 2 - llvm/test/CodeGen/PowerPC/htm.ll | 20 ++++++++++ .../Disassembler/PowerPC/ppc64-encoding-p8htm.txt | 43 ++++++++++++++++++++++ 7 files changed, 91 insertions(+), 33 deletions(-) create mode 100644 llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-p8htm.txt diff --git a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp index 4814529..7a8af57 100644 --- a/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp +++ b/llvm/lib/Target/PowerPC/Disassembler/PPCDisassembler.cpp @@ -86,12 +86,6 @@ static DecodeStatus DecodeCRRCRegisterClass(MCInst &Inst, uint64_t RegNo, return decodeRegisterClass(Inst, RegNo, CRRegs); } -static DecodeStatus DecodeCRRC0RegisterClass(MCInst &Inst, uint64_t RegNo, - uint64_t Address, - const void *Decoder) { - return decodeRegisterClass(Inst, RegNo, CRRegs); -} - static DecodeStatus DecodeCRBITRCRegisterClass(MCInst &Inst, uint64_t RegNo, uint64_t Address, const void *Decoder) { diff --git a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp index 621a3e9..b1ff161a 100644 --- a/llvm/lib/Target/PowerPC/PPCISelLowering.cpp +++ b/llvm/lib/Target/PowerPC/PPCISelLowering.cpp @@ -11267,7 +11267,16 @@ PPCTargetLowering::EmitInstrWithCustomInserter(MachineInstr &MI, MachineRegisterInfo &RegInfo = F->getRegInfo(); unsigned CRReg = RegInfo.createVirtualRegister(&PPC::CRRCRegClass); BuildMI(*BB, MI, Dl, TII->get(PPC::TCHECK), CRReg); - return BB; + BuildMI(*BB, MI, Dl, TII->get(TargetOpcode::COPY), + MI.getOperand(0).getReg()) + .addReg(CRReg); + } else if (MI.getOpcode() == PPC::TBEGIN_RET) { + DebugLoc Dl = MI.getDebugLoc(); + unsigned Imm = MI.getOperand(1).getImm(); + BuildMI(*BB, MI, Dl, TII->get(PPC::TBEGIN)).addImm(Imm); + BuildMI(*BB, MI, Dl, TII->get(TargetOpcode::COPY), + MI.getOperand(0).getReg()) + .addReg(PPC::CR0EQ); } else if (MI.getOpcode() == PPC::SETRNDi) { DebugLoc dl = MI.getDebugLoc(); unsigned OldFPSCRReg = MI.getOperand(0).getReg(); diff --git a/llvm/lib/Target/PowerPC/PPCInstrHTM.td b/llvm/lib/Target/PowerPC/PPCInstrHTM.td index f35f37d..1af65fb 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrHTM.td +++ b/llvm/lib/Target/PowerPC/PPCInstrHTM.td @@ -20,55 +20,53 @@ def HTM_get_imm : SDNodeXForm; let hasSideEffects = 1 in { -def TCHECK_RET : PPCCustomInserterPseudo<(outs crrc:$out), (ins), "#TCHECK_RET", []>; +def TCHECK_RET : PPCCustomInserterPseudo<(outs gprc:$out), (ins), "#TCHECK_RET", []>; +def TBEGIN_RET : PPCCustomInserterPseudo<(outs gprc:$out), (ins u1imm:$R), "#TBEGIN_RET", []>; } let Predicates = [HasHTM] in { +let Defs = [CR0] in { def TBEGIN : XForm_htm0 <31, 654, - (outs crrc0:$ret), (ins u1imm:$R), "tbegin. $R", IIC_SprMTSPR, []>; + (outs), (ins u1imm:$R), "tbegin. $R", IIC_SprMTSPR, []>; def TEND : XForm_htm1 <31, 686, - (outs crrc0:$ret), (ins u1imm:$A), "tend. $A", IIC_SprMTSPR, []>; + (outs), (ins u1imm:$A), "tend. $A", IIC_SprMTSPR, []>; def TABORT : XForm_base_r3xo <31, 910, - (outs crrc0:$ret), (ins gprc:$A), "tabort. $A", IIC_SprMTSPR, + (outs), (ins gprc:$A), "tabort. $A", IIC_SprMTSPR, []>, isDOT { let RST = 0; let B = 0; } def TABORTWC : XForm_base_r3xo <31, 782, - (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, gprc:$B), + (outs), (ins u5imm:$RTS, gprc:$A, gprc:$B), "tabortwc. $RTS, $A, $B", IIC_SprMTSPR, []>, isDOT; def TABORTWCI : XForm_base_r3xo <31, 846, - (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, u5imm:$B), + (outs), (ins u5imm:$RTS, gprc:$A, u5imm:$B), "tabortwci. $RTS, $A, $B", IIC_SprMTSPR, []>, isDOT; def TABORTDC : XForm_base_r3xo <31, 814, - (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, gprc:$B), + (outs), (ins u5imm:$RTS, gprc:$A, gprc:$B), "tabortdc. $RTS, $A, $B", IIC_SprMTSPR, []>, isDOT; def TABORTDCI : XForm_base_r3xo <31, 878, - (outs crrc0:$ret), (ins u5imm:$RTS, gprc:$A, u5imm:$B), + (outs), (ins u5imm:$RTS, gprc:$A, u5imm:$B), "tabortdci. $RTS, $A, $B", IIC_SprMTSPR, []>, isDOT; def TSR : XForm_htm2 <31, 750, - (outs crrc0:$ret), (ins u1imm:$L), "tsr. $L", IIC_SprMTSPR, []>, + (outs), (ins u1imm:$L), "tsr. $L", IIC_SprMTSPR, []>, isDOT; -def TCHECK : XForm_htm3 <31, 718, - (outs), (ins crrc:$BF), "tcheck $BF", IIC_SprMTSPR, []>; - - def TRECLAIM : XForm_base_r3xo <31, 942, - (outs crrc:$ret), (ins gprc:$A), "treclaim. $A", + (outs), (ins gprc:$A), "treclaim. $A", IIC_SprMTSPR, []>, isDOT { let RST = 0; @@ -76,13 +74,17 @@ def TRECLAIM : XForm_base_r3xo <31, 942, } def TRECHKPT : XForm_base_r3xo <31, 1006, - (outs crrc:$ret), (ins), "trechkpt.", IIC_SprMTSPR, []>, + (outs), (ins), "trechkpt.", IIC_SprMTSPR, []>, isDOT { let RST = 0; let A = 0; let B = 0; } +} + +def TCHECK : XForm_htm3 <31, 718, + (outs crrc:$BF), (ins), "tcheck $BF", IIC_SprMTSPR, []>; // Builtins // All HTM instructions, with the exception of tcheck, set CR0 with the @@ -93,15 +95,11 @@ def TRECHKPT : XForm_base_r3xo <31, 1006, // tbegin builtin API which defines a return value of 1 as success. def : Pat<(int_ppc_tbegin i32:$R), - (XORI - (EXTRACT_SUBREG ( - TBEGIN (HTM_get_imm imm:$R)), sub_eq), - 1)>; + (XORI (TBEGIN_RET(HTM_get_imm imm:$R)), 1)>; def : Pat<(int_ppc_tend i32:$R), (TEND (HTM_get_imm imm:$R))>; - def : Pat<(int_ppc_tabort i32:$R), (TABORT $R)>; diff --git a/llvm/lib/Target/PowerPC/PPCInstrInfo.td b/llvm/lib/Target/PowerPC/PPCInstrInfo.td index 5f98059..c313337 100644 --- a/llvm/lib/Target/PowerPC/PPCInstrInfo.td +++ b/llvm/lib/Target/PowerPC/PPCInstrInfo.td @@ -568,10 +568,6 @@ def PPCRegCRRCAsmOperand : AsmOperandClass { def crrc : RegisterOperand { let ParserMatchClass = PPCRegCRRCAsmOperand; } -def crrc0 : RegisterOperand { - let ParserMatchClass = PPCRegCRRCAsmOperand; -} - def PPCRegSPERCAsmOperand : AsmOperandClass { let Name = "RegSPERC"; let PredicateMethod = "isRegNumber"; } diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td index 3798eb4..af0dff6 100644 --- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.td +++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.td @@ -374,8 +374,6 @@ def CRBITRC : RegisterClass<"PPC", [i1], 32, def CRRC : RegisterClass<"PPC", [i32], 32, (add CR0, CR1, CR5, CR6, CR7, CR2, CR3, CR4)>; -def CRRC0 : RegisterClass<"PPC", [i32], 32, (add CR0)>; - // The CTR registers are not allocatable because they're used by the // decrement-and-branch instructions, and thus need to stay live across // multiple basic blocks. diff --git a/llvm/test/CodeGen/PowerPC/htm.ll b/llvm/test/CodeGen/PowerPC/htm.ll index cd91720..9b81de5 100644 --- a/llvm/test/CodeGen/PowerPC/htm.ll +++ b/llvm/test/CodeGen/PowerPC/htm.ll @@ -126,3 +126,23 @@ declare i64 @llvm.ppc.get.texasr() declare i64 @llvm.ppc.get.texasru() declare i64 @llvm.ppc.get.tfhar() declare i64 @llvm.ppc.get.tfiar() + +define void @test10() { +entry: + %0 = tail call i32 @llvm.ppc.tcheck() + %1 = tail call i32 @llvm.ppc.treclaim(i32 5) + %2 = tail call i32 @llvm.ppc.trechkpt() + %3 = tail call i32 @llvm.ppc.tsr(i32 1) + ret void +; CHECK-LABEL: @test10 +; CHECK: tcheck [[REG1:[0-9]+]] +; CHECK: treclaim. [[REG2:[0-9]+]] +; CHECK: trechkpt. +; CHECK: tsr. 1 +} + +declare i32 @llvm.ppc.tcheck() +declare i32 @llvm.ppc.treclaim(i32) +declare i32 @llvm.ppc.trechkpt() +declare i32 @llvm.ppc.tsr(i32) + diff --git a/llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-p8htm.txt b/llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-p8htm.txt new file mode 100644 index 0000000..57d9847 --- /dev/null +++ b/llvm/test/MC/Disassembler/PowerPC/ppc64-encoding-p8htm.txt @@ -0,0 +1,43 @@ +# RUN: llvm-mc --disassemble %s -triple powerpc64-unknown-unknown -mcpu=pwr8 | FileCheck %s + +# CHECK: tbegin. 1 +0x7c 0x20 0x05 0x1d + +# CHECK: tbegin. 0 +0x7c 0x00 0x05 0x1d + +# CHECK: tend. 0 +0x7c 0x00 0x05 0x5d + +# CHECK: tend. 1 +0x7e 0x00 0x05 0x5d + +# CHECK: tabort. 3 +0x7c 0x03 0x07 0x1d + +# CHECK: tabortdc. 9, 0, 0 +0x7d 0x20 0x06 0x5d + +# CHECK: tabortdci. 1, 0, 3 +0x7c 0x20 0x1e 0xdd + +# CHECK: tabortwc. 0, 4, 3 +0x7c 0x04 0x1e 0x1d + +# CHECK: tabortwci. 0, 4, 2 +0x7c 0x04 0x16 0x9d + +# CHECK: tsr. 1 +0x7c 0x20 0x05 0xdd + +# CHECK: tsr. 0 +0x7c 0x00 0x05 0xdd + +# CHECK: tcheck 0 +0x7c 0x00 0x05 0x9c + +# CHECK: treclaim. 3 +0x7c 0x03 0x07 0x5d + +# CHECK: trechkpt. +0x7c 0x00 0x07 0xdd -- 2.7.4