summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-11-01 20:42:24 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-11-01 20:42:24 +0000
commit2d8c289b4bd0d244e4743a41729184b90486517f (patch)
treefb44b0b9fc49d1ac86ea87bcd8b34e62f65a0b16
parent306b62b4aed8631b585fe0ee4f0532ca7ac53c37 (diff)
downloadbcm5719-llvm-2d8c289b4bd0d244e4743a41729184b90486517f.tar.gz
bcm5719-llvm-2d8c289b4bd0d244e4743a41729184b90486517f.zip
AMDGPU: Workaround for instruction size with literals
Instructions with a 32-bit base encoding with an optional 32-bit literal encoded after them report their size as 4 for the disassembler. Consider these when computing the MachineInstr size. This fixes problems caused by size estimate consistency in BranchRelaxation. llvm-svn: 285743
-rw-r--r--llvm/lib/Target/AMDGPU/SIDefines.h3
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrFormats.td5
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrInfo.cpp13
-rw-r--r--llvm/lib/Target/AMDGPU/SIInstrInfo.h8
-rw-r--r--llvm/lib/Target/AMDGPU/SOPInstructions.td1
5 files changed, 28 insertions, 2 deletions
diff --git a/llvm/lib/Target/AMDGPU/SIDefines.h b/llvm/lib/Target/AMDGPU/SIDefines.h
index f48011fe5e1..5e6e754b532 100644
--- a/llvm/lib/Target/AMDGPU/SIDefines.h
+++ b/llvm/lib/Target/AMDGPU/SIDefines.h
@@ -45,7 +45,8 @@ enum {
Gather4 = 1 << 26,
DisableWQM = 1 << 27,
SOPK_ZEXT = 1 << 28,
- SCALAR_STORE = 1 << 29
+ SCALAR_STORE = 1 << 29,
+ FIXED_SIZE = 1 << 30
};
}
diff --git a/llvm/lib/Target/AMDGPU/SIInstrFormats.td b/llvm/lib/Target/AMDGPU/SIInstrFormats.td
index 8976333412b..9dfe06fbb8e 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrFormats.td
+++ b/llvm/lib/Target/AMDGPU/SIInstrFormats.td
@@ -65,6 +65,10 @@ class InstSI <dag outs, dag ins, string asm = "",
// SMEM instructions like the cache flush ones.
field bits<1> ScalarStore = 0;
+ // Whether the operands can be ignored when computing the
+ // instruction size.
+ field bits<1> FixedSize = 0;
+
// These need to be kept in sync with the enum in SIInstrFlags.
let TSFlags{0} = VM_CNT;
let TSFlags{1} = EXP_CNT;
@@ -100,6 +104,7 @@ class InstSI <dag outs, dag ins, string asm = "",
let TSFlags{27} = DisableWQM;
let TSFlags{28} = SOPKZext;
let TSFlags{29} = ScalarStore;
+ let TSFlags{30} = FixedSize;
let SchedRW = [Write32Bit];
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
index cdd98c6ae71..905ee467319 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.cpp
@@ -3501,12 +3501,20 @@ unsigned SIInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
// If we have a definitive size, we can use it. Otherwise we need to inspect
// the operands to know the size.
- if (DescSize != 0)
+ //
+ // FIXME: Instructions that have a base 32-bit encoding report their size as
+ // 4, even though they are really 8 bytes if they have a literal operand.
+ if (DescSize != 0 && DescSize != 4)
return DescSize;
// 4-byte instructions may have a 32-bit literal encoded after them. Check
// operands that coud ever be literals.
if (isVALU(MI) || isSALU(MI)) {
+ if (isFixedSize(MI)) {
+ assert(DescSize == 4);
+ return DescSize;
+ }
+
int Src0Idx = AMDGPU::getNamedOperandIdx(Opc, AMDGPU::OpName::src0);
if (Src0Idx == -1)
return 4; // No operands.
@@ -3524,6 +3532,9 @@ unsigned SIInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
return 4;
}
+ if (DescSize == 4)
+ return 4;
+
switch (Opc) {
case AMDGPU::SI_MASK_BRANCH:
case TargetOpcode::IMPLICIT_DEF:
diff --git a/llvm/lib/Target/AMDGPU/SIInstrInfo.h b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
index b83d2cd97f6..515beb4bbfd 100644
--- a/llvm/lib/Target/AMDGPU/SIInstrInfo.h
+++ b/llvm/lib/Target/AMDGPU/SIInstrInfo.h
@@ -438,6 +438,14 @@ public:
return get(Opcode).TSFlags & SIInstrFlags::SCALAR_STORE;
}
+ static bool isFixedSize(const MachineInstr &MI) {
+ return MI.getDesc().TSFlags & SIInstrFlags::FIXED_SIZE;
+ }
+
+ bool isFixedSize(uint16_t Opcode) const {
+ return get(Opcode).TSFlags & SIInstrFlags::FIXED_SIZE;
+ }
+
bool isVGPRCopy(const MachineInstr &MI) const {
assert(MI.isCopy());
unsigned Dest = MI.getOperand(0).getReg();
diff --git a/llvm/lib/Target/AMDGPU/SOPInstructions.td b/llvm/lib/Target/AMDGPU/SOPInstructions.td
index 0d376b97b5f..e38a11db9ac 100644
--- a/llvm/lib/Target/AMDGPU/SOPInstructions.td
+++ b/llvm/lib/Target/AMDGPU/SOPInstructions.td
@@ -704,6 +704,7 @@ def S_SET_GPR_IDX_ON : SOPC <0x11,
let Defs = [M0]; // No scc def
let Uses = [M0]; // Other bits of m0 unmodified.
let hasSideEffects = 1; // Sets mode.gpr_idx_en
+ let FixedSize = 1;
}
}
OpenPOWER on IntegriCloud