From 82d457bf36c82ef315d338c7bd066ec1a612693f Mon Sep 17 00:00:00 2001 From: Sjoerd Meijer Date: Wed, 14 Sep 2016 08:20:03 +0000 Subject: [PATCH] This reapplies r281304. The issue was that I had missed to copy the new isAdd field in the tablegen data structure. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@281447 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/MC/MCInstrDesc.h | 6 +- include/llvm/Target/Target.td | 1 + lib/Target/ARM/ARMInstrInfo.td | 3 + lib/Target/ARM/ARMInstrThumb.td | 86 +++++++++++---------- lib/Target/ARM/ARMInstrThumb2.td | 1 + lib/Target/Hexagon/HexagonHardwareLoops.cpp | 8 +- lib/Target/Hexagon/HexagonInstrInfo.td | 3 +- test/CodeGen/Hexagon/addh-sext-trunc.ll | 30 ++----- utils/TableGen/CodeGenInstruction.cpp | 1 + utils/TableGen/CodeGenInstruction.h | 1 + utils/TableGen/InstrInfoEmitter.cpp | 1 + 11 files changed, 66 insertions(+), 75 deletions(-) diff --git a/include/llvm/MC/MCInstrDesc.h b/include/llvm/MC/MCInstrDesc.h index 84b27219d08..d7887efbbf6 100644 --- a/include/llvm/MC/MCInstrDesc.h +++ b/include/llvm/MC/MCInstrDesc.h @@ -150,7 +150,8 @@ enum Flag { RegSequence, ExtractSubreg, InsertSubreg, - Convergent + Convergent, + Add }; } @@ -234,6 +235,9 @@ public: /// \brief Return true if the instruction is a return. bool isReturn() const { return Flags & (1ULL << MCID::Return); } + /// \brief Return true if the instruction is an add instruction. + bool isAdd() const { return Flags & (1ULL << MCID::Add); } + /// \brief Return true if the instruction is a call. bool isCall() const { return Flags & (1ULL << MCID::Call); } diff --git a/include/llvm/Target/Target.td b/include/llvm/Target/Target.td index 03f334c7404..2689156e208 100644 --- a/include/llvm/Target/Target.td +++ b/include/llvm/Target/Target.td @@ -371,6 +371,7 @@ class Instruction { bit isSelect = 0; // Is this instruction a select instruction? bit isBarrier = 0; // Can control flow fall through this instruction? bit isCall = 0; // Is this instruction a call instruction? + bit isAdd = 0; // Is this instruction an add instruction? bit canFoldAsLoad = 0; // Can this be folded as a simple memory operand? bit mayLoad = ?; // Is it possible for this inst to read memory? bit mayStore = ?; // Is it possible for this inst to write memory? diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index cda8bb70f1c..2f1b12d7293 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -3498,6 +3498,7 @@ def UBFX : I<(outs GPRnopc:$Rd), // Arithmetic Instructions. // +let isAdd = 1 in defm ADD : AsI1_bin_irs<0b0100, "add", IIC_iALUi, IIC_iALUr, IIC_iALUsr, add, 1>; defm SUB : AsI1_bin_irs<0b0010, "sub", @@ -3513,9 +3514,11 @@ defm SUB : AsI1_bin_irs<0b0010, "sub", // FIXME: Eliminate ADDS/SUBS pseudo opcodes after adding tablegen // support for an optional CPSR definition that corresponds to the DAG // node's second value. We can then eliminate the implicit def of CPSR. +let isAdd = 1 in defm ADDS : AsI1_bin_s_irs; defm SUBS : AsI1_bin_s_irs; +let isAdd = 1 in defm ADC : AI1_adde_sube_irs<0b0101, "adc", ARMadde, 1>; defm SBC : AI1_adde_sube_irs<0b0110, "sbc", ARMsube>; diff --git a/lib/Target/ARM/ARMInstrThumb.td b/lib/Target/ARM/ARMInstrThumb.td index 93a174f3678..72623a45034 100644 --- a/lib/Target/ARM/ARMInstrThumb.td +++ b/lib/Target/ARM/ARMInstrThumb.td @@ -904,49 +904,51 @@ class T1sItGenEncodeImm opA, dag oops, dag iops, InstrItinClass itin, let Inst{7-0} = imm8; } -// Add with carry register -let isCommutable = 1, Uses = [CPSR] in -def tADC : // A8.6.2 - T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr, - "adc", "\t$Rdn, $Rm", - [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; - -// Add immediate -def tADDi3 : // A8.6.4 T1 - T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3), - IIC_iALUi, - "add", "\t$Rd, $Rm, $imm3", - [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>, - Sched<[WriteALU]> { - bits<3> imm3; - let Inst{8-6} = imm3; -} - -def tADDi8 : // A8.6.4 T2 - T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn), - (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi, - "add", "\t$Rdn, $imm8", - [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>, - Sched<[WriteALU]>; +let isAdd = 1 in { + // Add with carry register + let isCommutable = 1, Uses = [CPSR] in + def tADC : // A8.6.2 + T1sItDPEncode<0b0101, (outs tGPR:$Rdn), (ins tGPR:$Rn, tGPR:$Rm), IIC_iALUr, + "adc", "\t$Rdn, $Rm", + [(set tGPR:$Rdn, (adde tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; + + // Add immediate + def tADDi3 : // A8.6.4 T1 + T1sIGenEncodeImm<0b01110, (outs tGPR:$Rd), (ins tGPR:$Rm, imm0_7:$imm3), + IIC_iALUi, + "add", "\t$Rd, $Rm, $imm3", + [(set tGPR:$Rd, (add tGPR:$Rm, imm0_7:$imm3))]>, + Sched<[WriteALU]> { + bits<3> imm3; + let Inst{8-6} = imm3; + } -// Add register -let isCommutable = 1 in -def tADDrr : // A8.6.6 T1 - T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), - IIC_iALUr, - "add", "\t$Rd, $Rn, $Rm", - [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; - -let hasSideEffects = 0 in -def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr, - "add", "\t$Rdn, $Rm", []>, - T1Special<{0,0,?,?}>, Sched<[WriteALU]> { - // A8.6.6 T2 - bits<4> Rdn; - bits<4> Rm; - let Inst{7} = Rdn{3}; - let Inst{6-3} = Rm; - let Inst{2-0} = Rdn{2-0}; + def tADDi8 : // A8.6.4 T2 + T1sItGenEncodeImm<{1,1,0,?,?}, (outs tGPR:$Rdn), + (ins tGPR:$Rn, imm0_255:$imm8), IIC_iALUi, + "add", "\t$Rdn, $imm8", + [(set tGPR:$Rdn, (add tGPR:$Rn, imm8_255:$imm8))]>, + Sched<[WriteALU]>; + + // Add register + let isCommutable = 1 in + def tADDrr : // A8.6.6 T1 + T1sIGenEncode<0b01100, (outs tGPR:$Rd), (ins tGPR:$Rn, tGPR:$Rm), + IIC_iALUr, + "add", "\t$Rd, $Rn, $Rm", + [(set tGPR:$Rd, (add tGPR:$Rn, tGPR:$Rm))]>, Sched<[WriteALU]>; + + let hasSideEffects = 0 in + def tADDhirr : T1pIt<(outs GPR:$Rdn), (ins GPR:$Rn, GPR:$Rm), IIC_iALUr, + "add", "\t$Rdn, $Rm", []>, + T1Special<{0,0,?,?}>, Sched<[WriteALU]> { + // A8.6.6 T2 + bits<4> Rdn; + bits<4> Rm; + let Inst{7} = Rdn{3}; + let Inst{6-3} = Rm; + let Inst{2-0} = Rdn{2-0}; + } } // AND register diff --git a/lib/Target/ARM/ARMInstrThumb2.td b/lib/Target/ARM/ARMInstrThumb2.td index 9a2dee9048b..c47b871abcc 100644 --- a/lib/Target/ARM/ARMInstrThumb2.td +++ b/lib/Target/ARM/ARMInstrThumb2.td @@ -2038,6 +2038,7 @@ def : Thumb2ExtractPat<(add rGPR:$Rn, (and (srl rGPR:$Rm, imm8_or_16:$rot), // Arithmetic Instructions. // +let isAdd = 1 in defm t2ADD : T2I_bin_ii12rs<0b000, "add", add, 1>; defm t2SUB : T2I_bin_ii12rs<0b101, "sub", sub>; diff --git a/lib/Target/Hexagon/HexagonHardwareLoops.cpp b/lib/Target/Hexagon/HexagonHardwareLoops.cpp index 930747faa0d..45e61485410 100644 --- a/lib/Target/Hexagon/HexagonHardwareLoops.cpp +++ b/lib/Target/Hexagon/HexagonHardwareLoops.cpp @@ -411,10 +411,8 @@ bool HexagonHardwareLoops::findInductionRegister(MachineLoop *L, unsigned PhiOpReg = Phi->getOperand(i).getReg(); MachineInstr *DI = MRI->getVRegDef(PhiOpReg); - unsigned UpdOpc = DI->getOpcode(); - bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp); - if (isAdd) { + if (DI->getDesc().isAdd()) { // If the register operand to the add is the PHI we're looking at, this // meets the induction pattern. unsigned IndReg = DI->getOperand(1).getReg(); @@ -1592,10 +1590,8 @@ bool HexagonHardwareLoops::fixupInductionVariable(MachineLoop *L) { unsigned PhiReg = Phi->getOperand(i).getReg(); MachineInstr *DI = MRI->getVRegDef(PhiReg); - unsigned UpdOpc = DI->getOpcode(); - bool isAdd = (UpdOpc == Hexagon::A2_addi || UpdOpc == Hexagon::A2_addp); - if (isAdd) { + if (DI->getDesc().isAdd()) { // If the register operand to the add/sub is the PHI we are looking // at, this meets the induction pattern. unsigned IndReg = DI->getOperand(1).getReg(); diff --git a/lib/Target/Hexagon/HexagonInstrInfo.td b/lib/Target/Hexagon/HexagonInstrInfo.td index 26e18b9916a..fd2c7a73de5 100644 --- a/lib/Target/Hexagon/HexagonInstrInfo.td +++ b/lib/Target/Hexagon/HexagonInstrInfo.td @@ -406,7 +406,7 @@ multiclass Addri_Pred { let isExtendable = 1, isExtentSigned = 1, InputType = "imm" in multiclass Addri_base { let CextOpcode = mnemonic, BaseOpcode = mnemonic#_ri in { - let opExtendable = 2, opExtentBits = 16, isPredicable = 1 in + let opExtendable = 2, opExtentBits = 16, isPredicable = 1, isAdd = 1 in def A2_#NAME : T_Addri; let opExtendable = 3, opExtentBits = 8, isPredicated = 1 in { @@ -1292,6 +1292,7 @@ class T_ALU64_arith MajOp, bits<3> MinOp, bit IsSat, : T_ALU64_rr; +let isAdd = 1 in def A2_addp : T_ALU64_arith<"add", 0b000, 0b111, 0, 0, 1>; def A2_subp : T_ALU64_arith<"sub", 0b001, 0b111, 0, 1, 0>; diff --git a/test/CodeGen/Hexagon/addh-sext-trunc.ll b/test/CodeGen/Hexagon/addh-sext-trunc.ll index 094932933fb..7f219944436 100644 --- a/test/CodeGen/Hexagon/addh-sext-trunc.ll +++ b/test/CodeGen/Hexagon/addh-sext-trunc.ll @@ -4,37 +4,17 @@ target datalayout = "e-p:32:32:32-i64:64:64-i32:32:32-i16:16:16-i1:32:32-f64:64:64-f32:32:32-v64:64:64-v32:32:32-a0:0-n16:32" target triple = "hexagon-unknown-none" -%struct.aDataType = type { i16, i16, i16, i16, i16, i16*, i16*, i16*, i8*, i16*, i16*, i16*, i8* } -define i8* @a_get_score(%struct.aDataType* nocapture %pData, i16 signext %gmmModelIndex, i16* nocapture %pGmmScoreL16Q4) #0 { -entry: - %numSubVector = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 3 - %0 = load i16, i16* %numSubVector, align 2, !tbaa !0 - %and = and i16 %0, -4 - %b = getelementptr inbounds %struct.aDataType, %struct.aDataType* %pData, i32 0, i32 8 - %1 = load i8*, i8** %b, align 4, !tbaa !3 +define i32 @foo(i16 %a, i32 %b) #0 { + %and = and i16 %a, -4 %conv3 = sext i16 %and to i32 - %cmp21 = icmp sgt i16 %and, 0 - br i1 %cmp21, label %for.inc.preheader, label %for.end - -for.inc.preheader: ; preds = %entry - br label %for.inc - -for.inc: ; preds = %for.inc.preheader, %for.inc - %j.022 = phi i32 [ %phitmp, %for.inc ], [ 0, %for.inc.preheader ] - %add13 = mul i32 %j.022, 65536 + %add13 = mul i32 %b, 65536 %sext = add i32 %add13, 262144 %phitmp = ashr exact i32 %sext, 16 - %cmp = icmp slt i32 %phitmp, %conv3 - br i1 %cmp, label %for.inc, label %for.end.loopexit - -for.end.loopexit: ; preds = %for.inc - br label %for.end - -for.end: ; preds = %for.end.loopexit, %entry - ret i8* %1 + ret i32 %phitmp } + attributes #0 = { nounwind readonly "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-frame-pointer-elim-non-leaf"="true" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "unsafe-fp-math"="false" "use-soft-float"="false" } !0 = !{!"short", !1} diff --git a/utils/TableGen/CodeGenInstruction.cpp b/utils/TableGen/CodeGenInstruction.cpp index ec802363030..792aad87311 100644 --- a/utils/TableGen/CodeGenInstruction.cpp +++ b/utils/TableGen/CodeGenInstruction.cpp @@ -309,6 +309,7 @@ CodeGenInstruction::CodeGenInstruction(Record *R) isSelect = R->getValueAsBit("isSelect"); isBarrier = R->getValueAsBit("isBarrier"); isCall = R->getValueAsBit("isCall"); + isAdd = R->getValueAsBit("isAdd"); canFoldAsLoad = R->getValueAsBit("canFoldAsLoad"); isPredicable = Operands.isPredicable || R->getValueAsBit("isPredicable"); isConvertibleToThreeAddress = R->getValueAsBit("isConvertibleToThreeAddress"); diff --git a/utils/TableGen/CodeGenInstruction.h b/utils/TableGen/CodeGenInstruction.h index 8e5a03d7b74..75db17b59ac 100644 --- a/utils/TableGen/CodeGenInstruction.h +++ b/utils/TableGen/CodeGenInstruction.h @@ -230,6 +230,7 @@ template class ArrayRef; bool isSelect : 1; bool isBarrier : 1; bool isCall : 1; + bool isAdd : 1; bool canFoldAsLoad : 1; bool mayLoad : 1; bool mayLoad_Unset : 1; diff --git a/utils/TableGen/InstrInfoEmitter.cpp b/utils/TableGen/InstrInfoEmitter.cpp index 02461cc0508..e9c448d0445 100644 --- a/utils/TableGen/InstrInfoEmitter.cpp +++ b/utils/TableGen/InstrInfoEmitter.cpp @@ -482,6 +482,7 @@ void InstrInfoEmitter::emitRecord(const CodeGenInstruction &Inst, unsigned Num, if (Inst.isCompare) OS << "|(1ULL<