diff options
author | Tom Stellard <thomas.stellard@amd.com> | 2014-01-29 16:36:09 -0500 |
---|---|---|
committer | Tom Stellard <thomas.stellard@amd.com> | 2014-01-29 16:36:09 -0500 |
commit | abaae96727b5da5395d4f31dbd701489b45432ad (patch) | |
tree | 5904e57e9267bca4edc9e5a781c7eb4df59bff52 | |
parent | ecd39f7b9954e2903de26093e4b5235426bb2a6a (diff) |
R600/SI: Use immediates offsets for SMRD instructions whenever possiblemaster-testing-patches
There was a problem with the old pattern, so we were copying some
larger immediates into registers when we could have been encoding
them in the instruction.
-rw-r--r-- | lib/Target/R600/SIInstrInfo.td | 17 | ||||
-rw-r--r-- | lib/Target/R600/SIInstructions.td | 4 | ||||
-rw-r--r-- | test/CodeGen/R600/smrd.ll | 36 |
3 files changed, 48 insertions, 9 deletions
diff --git a/lib/Target/R600/SIInstrInfo.td b/lib/Target/R600/SIInstrInfo.td index 97d37d894ab..871509f1942 100644 --- a/lib/Target/R600/SIInstrInfo.td +++ b/lib/Target/R600/SIInstrInfo.td @@ -75,15 +75,14 @@ def HI32f : SDNodeXForm<fpimm, [{ return CurDAG->getTargetConstantFP(APFloat(APFloat::IEEEsingle, V), MVT::f32); }]>; -def IMM8bitDWORD : ImmLeaf < - i32, [{ - return (Imm & ~0x3FC) == 0; - }], SDNodeXForm<imm, [{ - return CurDAG->getTargetConstant( - N->getZExtValue() >> 2, MVT::i32); - }]> +def IMM8bitDWORD : PatLeaf <(imm), + [{return (N->getZExtValue() & ~0x3FC) == 0;}] >; +def as_dword_i32imm : SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(N->getZExtValue() >> 2, MVT::i32); +}]>; + def as_i1imm : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(N->getZExtValue(), MVT::i1); }]>; @@ -96,6 +95,10 @@ def as_i16imm : SDNodeXForm<imm, [{ return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i16); }]>; +def as_i32imm: SDNodeXForm<imm, [{ + return CurDAG->getTargetConstant(N->getSExtValue(), MVT::i32); +}]>; + def IMM12bit : PatLeaf <(imm), [{return isUInt<12>(N->getZExtValue());}] >; diff --git a/lib/Target/R600/SIInstructions.td b/lib/Target/R600/SIInstructions.td index cdd34e2bcfa..b82eaf4f73d 100644 --- a/lib/Target/R600/SIInstructions.td +++ b/lib/Target/R600/SIInstructions.td @@ -1904,8 +1904,8 @@ multiclass SMRD_Pattern <SMRD Instr_IMM, SMRD Instr_SGPR, ValueType vt> { // 1. Offset as 8bit DWORD immediate def : Pat < - (constant_load (SIadd64bit32bit i64:$sbase, IMM8bitDWORD:$offset)), - (vt (Instr_IMM $sbase, IMM8bitDWORD:$offset)) + (constant_load (add i64:$sbase, (i64 IMM8bitDWORD:$offset))), + (vt (Instr_IMM $sbase, (as_dword_i32imm $offset))) >; // 2. Offset loaded in an 32bit SGPR diff --git a/test/CodeGen/R600/smrd.ll b/test/CodeGen/R600/smrd.ll new file mode 100644 index 00000000000..94a5e95cdfe --- /dev/null +++ b/test/CodeGen/R600/smrd.ll @@ -0,0 +1,36 @@ +; RUN: llc < %s -march=r600 -mcpu=SI -show-mc-encoding -verify-machineinstrs | FileCheck %s + +; SMRD load with an immediate offset. +; CHECK-LABEL: @smrd0 +; CHECK: S_LOAD_DWORD s{{[0-9]}}, s[{{[0-9]:[0-9]}}], 1 ; encoding: [0x01 +define void @smrd0(i32 addrspace(1)* %out, i32 addrspace(2)* %ptr) { +entry: + %0 = getelementptr i32 addrspace(2)* %ptr, i64 1 + %1 = load i32 addrspace(2)* %0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; SMRD load with the largest possible immediate offset. +; CHECK-LABEL: @smrd1 +; CHECK: S_LOAD_DWORD s{{[0-9]}}, s[{{[0-9]:[0-9]}}], 255 ; encoding: [0xff +define void @smrd1(i32 addrspace(1)* %out, i32 addrspace(2)* %ptr) { +entry: + %0 = getelementptr i32 addrspace(2)* %ptr, i64 255 + %1 = load i32 addrspace(2)* %0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + +; SMRD load with an offset greater than the largest possible immediate. +; CHECK-LABEL: @smrd2 +; CHECK: S_MOV_B32 s[[OFFSET:[0-9]]], 1024 +; CHECK: S_LOAD_DWORD s{{[0-9]}}, s[{{[0-9]:[0-9]}}], s[[OFFSET]] ; encoding: [0x0[[OFFSET]] +define void @smrd2(i32 addrspace(1)* %out, i32 addrspace(2)* %ptr) { +entry: + %0 = getelementptr i32 addrspace(2)* %ptr, i64 256 + %1 = load i32 addrspace(2)* %0 + store i32 %1, i32 addrspace(1)* %out + ret void +} + |