From d0084464b5d22bcec1f912ddd8969a4a64727482 Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Mon, 17 Mar 2014 17:03:52 +0000 Subject: [PATCH] R600/SI: Fix implementation of isInlineConstant() used by the verifier MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 llvm-svn: 204056 --- llvm/lib/Target/R600/SIInstrInfo.cpp | 39 ++++++++++++++++++---------- llvm/test/CodeGen/R600/v_cndmask.ll | 13 ++++++++++ 2 files changed, 38 insertions(+), 14 deletions(-) create mode 100644 llvm/test/CodeGen/R600/v_cndmask.ll diff --git a/llvm/lib/Target/R600/SIInstrInfo.cpp b/llvm/lib/Target/R600/SIInstrInfo.cpp index f68dc2e0e49b..3ed8dfa325f3 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; + + 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; } - 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); - } - 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 000000000000..9253f76d9c52 --- /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 +}