summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTom Stellard <thomas.stellard@amd.com>2014-03-17 17:03:52 +0000
committerTom Stellard <thomas.stellard@amd.com>2014-03-17 17:03:52 +0000
commitd0084464b5d22bcec1f912ddd8969a4a64727482 (patch)
tree0aa9b1405360d96a4e1c233d26b724c506618430
parentfbe435de6317249d1eddf5d9850863a7f22f0934 (diff)
downloadbcm5719-llvm-d0084464b5d22bcec1f912ddd8969a4a64727482.tar.gz
bcm5719-llvm-d0084464b5d22bcec1f912ddd8969a4a64727482.zip
R600/SI: Fix implementation of isInlineConstant() used by the verifier
The type of the immediates should not matter as long as the encoding is equivalent to the encoding of one of the legal inline constants. Tested-by: Michel Dänzer <michel.daenzer@amd.com> llvm-svn: 204056
-rw-r--r--llvm/lib/Target/R600/SIInstrInfo.cpp39
-rw-r--r--llvm/test/CodeGen/R600/v_cndmask.ll13
2 files changed, 38 insertions, 14 deletions
diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp
index f68dc2e0e49..3ed8dfa325f 100644
--- a/llvm/lib/Target/R600/SIInstrInfo.cpp
+++ b/llvm/lib/Target/R600/SIInstrInfo.cpp
@@ -349,21 +349,32 @@ bool SIInstrInfo::isSALUInstr(const MachineInstr &MI) const {
}
bool SIInstrInfo::isInlineConstant(const MachineOperand &MO) const {
- if(MO.isImm()) {
- return MO.getImm() >= -16 && MO.getImm() <= 64;
- }
- if (MO.isFPImm()) {
- return MO.getFPImm()->isExactlyValue(0.0) ||
- MO.getFPImm()->isExactlyValue(0.5) ||
- MO.getFPImm()->isExactlyValue(-0.5) ||
- MO.getFPImm()->isExactlyValue(1.0) ||
- MO.getFPImm()->isExactlyValue(-1.0) ||
- MO.getFPImm()->isExactlyValue(2.0) ||
- MO.getFPImm()->isExactlyValue(-2.0) ||
- MO.getFPImm()->isExactlyValue(4.0) ||
- MO.getFPImm()->isExactlyValue(-4.0);
+
+ union {
+ int32_t I;
+ float F;
+ } Imm;
+
+ if (MO.isImm()) {
+ Imm.I = MO.getImm();
+ } else if (MO.isFPImm()) {
+ Imm.F = MO.getFPImm()->getValueAPF().convertToFloat();
+ } else {
+ return false;
}
- return false;
+
+ // The actual type of the operand does not seem to matter as long
+ // as the bits match one of the inline immediate values. For example:
+ //
+ // -nan has the hexadecimal encoding of 0xfffffffe which is -2 in decimal,
+ // so it is a legal inline immediate.
+ //
+ // 1065353216 has the hexadecimal encoding 0x3f800000 which is 1.0f in
+ // floating-point, so it is a legal inline immediate.
+ return (Imm.I >= -16 && Imm.I <= 64) ||
+ Imm.F == 0.0f || Imm.F == 0.5f || Imm.F == -0.5f || Imm.F == 1.0f ||
+ Imm.F == -1.0f || Imm.F == 2.0f || Imm.F == -2.0f || Imm.F == 4.0f ||
+ Imm.F == -4.0f;
}
bool SIInstrInfo::isLiteralConstant(const MachineOperand &MO) const {
diff --git a/llvm/test/CodeGen/R600/v_cndmask.ll b/llvm/test/CodeGen/R600/v_cndmask.ll
new file mode 100644
index 00000000000..9253f76d9c5
--- /dev/null
+++ b/llvm/test/CodeGen/R600/v_cndmask.ll
@@ -0,0 +1,13 @@
+; RUN: llc < %s -march=r600 -mcpu=SI -verify-machineinstrs | FileCheck --check-prefix=SI %s
+
+; SI: @v_cnd_nan
+; SI: V_CNDMASK_B32_e64 v{{[0-9]}},
+; SI-DAG: v{{[0-9]}}
+; SI-DAG: -nan
+define void @v_cnd_nan(float addrspace(1)* %out, i32 %c, float %f) {
+entry:
+ %0 = icmp ne i32 %c, 0
+ %1 = select i1 %0, float 0xFFFFFFFFE0000000, float %f
+ store float %1, float addrspace(1)* %out
+ ret void
+}
OpenPOWER on IntegriCloud