[llvm] r204056 - R600/SI: Fix implementation of isInlineConstant() used by the verifier

Tom Stellard thomas.stellard at amd.com
Mon Mar 17 10:03:52 PDT 2014


Author: tstellar
Date: Mon Mar 17 12:03:52 2014
New Revision: 204056

URL: http://llvm.org/viewvc/llvm-project?rev=204056&view=rev
Log:
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 at amd.com>

Added:
    llvm/trunk/test/CodeGen/R600/v_cndmask.ll
Modified:
    llvm/trunk/lib/Target/R600/SIInstrInfo.cpp

Modified: llvm/trunk/lib/Target/R600/SIInstrInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/R600/SIInstrInfo.cpp?rev=204056&r1=204055&r2=204056&view=diff
==============================================================================
--- llvm/trunk/lib/Target/R600/SIInstrInfo.cpp (original)
+++ llvm/trunk/lib/Target/R600/SIInstrInfo.cpp Mon Mar 17 12:03:52 2014
@@ -349,21 +349,32 @@ bool SIInstrInfo::isSALUInstr(const Mach
 }
 
 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 {

Added: llvm/trunk/test/CodeGen/R600/v_cndmask.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/R600/v_cndmask.ll?rev=204056&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/R600/v_cndmask.ll (added)
+++ llvm/trunk/test/CodeGen/R600/v_cndmask.ll Mon Mar 17 12:03:52 2014
@@ -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
+}





More information about the llvm-commits mailing list