From edbf1eb42be8108bd4d16674f77a08ea391f06fa Mon Sep 17 00:00:00 2001 From: Tom Stellard Date: Fri, 5 Apr 2013 23:31:20 +0000 Subject: [PATCH] R600/SI: Avoid generating S_MOVs with 64-bit immediates v2 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit SITargetLowering::analyzeImmediate() was converting the 64-bit values to 32-bit and then checking if they were an inline immediate. Some of these conversions caused this check to succeed and produced S_MOV instructions with 64-bit immediates, which are illegal. v2: - Clean up logic Reviewed-by: Christian König llvm-svn: 178927 --- llvm/lib/Target/R600/SIISelLowering.cpp | 7 +++++-- llvm/test/CodeGen/R600/imm.ll | 26 +++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) create mode 100644 llvm/test/CodeGen/R600/imm.ll diff --git a/llvm/lib/Target/R600/SIISelLowering.cpp b/llvm/lib/Target/R600/SIISelLowering.cpp index 6f0c30761506..7fa28d9532cb 100644 --- a/llvm/lib/Target/R600/SIISelLowering.cpp +++ b/llvm/lib/Target/R600/SIISelLowering.cpp @@ -424,9 +424,12 @@ int32_t SITargetLowering::analyzeImmediate(const SDNode *N) const { float F; } Imm; - if (const ConstantSDNode *Node = dyn_cast(N)) + if (const ConstantSDNode *Node = dyn_cast(N)) { + if (Node->getZExtValue() >> 32) { + return -1; + } Imm.I = Node->getSExtValue(); - else if (const ConstantFPSDNode *Node = dyn_cast(N)) + } else if (const ConstantFPSDNode *Node = dyn_cast(N)) Imm.F = Node->getValueAPF().convertToFloat(); else return -1; // It isn't an immediate diff --git a/llvm/test/CodeGen/R600/imm.ll b/llvm/test/CodeGen/R600/imm.ll new file mode 100644 index 000000000000..b43f91722e2f --- /dev/null +++ b/llvm/test/CodeGen/R600/imm.ll @@ -0,0 +1,26 @@ +; RUN: llc < %s -march=r600 -mcpu=SI | FileCheck %s + +; XXX: Enable once SI supports buffer stores +; XFAIL: * + +; Use a 64-bit value with lo bits that can be represented as an inline constant +; CHECK: @i64_imm_inline_lo +; CHECK: S_MOV_B32 [[LO:SGPR[0-9]+]], 5 +; CHECK: V_MOV_B32_e32 [[LO_VGPR:VGPR[0-9]+]], [[LO]] +; CHECK: BUFFER_STORE_DWORDX2 [[LO_VGPR]]_ +define void @i64_imm_inline_lo(i64 addrspace(1) *%out) { +entry: + store i64 1311768464867721221, i64 addrspace(1) *%out ; 0x1234567800000005 + ret void +} + +; Use a 64-bit value with hi bits that can be represented as an inline constant +; CHECK: @i64_imm_inline_hi +; CHECK: S_MOV_B32 [[HI:SGPR[0-9]+]], 5 +; CHECK: V_MOV_B32_e32 [[HI_VGPR:VGPR[0-9]+]], [[HI]] +; CHECK: BUFFER_STORE_DWORDX2 {{VGPR[0-9]+}}_[[HI_VGPR]] +define void @i64_imm_inline_hi(i64 addrspace(1) *%out) { +entry: + store i64 21780256376, i64 addrspace(1) *%out ; 0x0000000512345678 + ret void +}