diff --git a/lib/Target/R600/SIISelLowering.cpp b/lib/Target/R600/SIISelLowering.cpp index 6f0c3076150..7fa28d9532c 100644 --- a/lib/Target/R600/SIISelLowering.cpp +++ b/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/test/CodeGen/R600/imm.ll b/test/CodeGen/R600/imm.ll new file mode 100644 index 00000000000..b43f91722e2 --- /dev/null +++ b/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 +}