From dc28955b3f48116fe76ef98c778aa64e51ef62db Mon Sep 17 00:00:00 2001 From: Anton Korobeynikov Date: Thu, 16 Jul 2009 13:44:30 +0000 Subject: [PATCH] Add patterns for various extloads git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@75930 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Target/SystemZ/SystemZISelDAGToDAG.cpp | 3 + lib/Target/SystemZ/SystemZInstrInfo.td | 42 +++++++++++- test/CodeGen/SystemZ/05-MemRegLoads.ll | 75 ++++++++++++++++++++++ 3 files changed, 119 insertions(+), 1 deletion(-) create mode 100644 test/CodeGen/SystemZ/05-MemRegLoads.ll diff --git a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp index e379c6999aa..83fea60bef5 100644 --- a/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp +++ b/lib/Target/SystemZ/SystemZISelDAGToDAG.cpp @@ -221,6 +221,9 @@ bool SystemZDAGToDAGISel::MatchAddress(SDValue N, SystemZRRIAddressMode &AM, if (Depth > 5) return MatchAddressBase(N, AM); + // FIXME: We can perform better here. If we have something like + // (shift (add A, imm), N), we can try to reassociate stuff and fold shift of + // imm into addressing mode. switch (N.getOpcode()) { default: break; case ISD::Constant: { diff --git a/lib/Target/SystemZ/SystemZInstrInfo.td b/lib/Target/SystemZ/SystemZInstrInfo.td index 80171542a3d..8bf4b4fe58a 100644 --- a/lib/Target/SystemZ/SystemZInstrInfo.td +++ b/lib/Target/SystemZ/SystemZInstrInfo.td @@ -108,6 +108,20 @@ def i64hi32 : PatLeaf<(i64 imm), [{ return ((N->getZExtValue() & 0xFFFFFFFF00000000ULL) == N->getZExtValue()); }], HI32>; +// extloads +def extloadi64i8 : PatFrag<(ops node:$ptr), (i64 (extloadi8 node:$ptr))>; +def extloadi64i16 : PatFrag<(ops node:$ptr), (i64 (extloadi16 node:$ptr))>; +def extloadi64i32 : PatFrag<(ops node:$ptr), (i64 (extloadi32 node:$ptr))>; + +def sextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (sextloadi8 node:$ptr))>; +def sextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (sextloadi16 node:$ptr))>; +def sextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (sextloadi32 node:$ptr))>; + +def zextloadi64i8 : PatFrag<(ops node:$ptr), (i64 (zextloadi8 node:$ptr))>; +def zextloadi64i16 : PatFrag<(ops node:$ptr), (i64 (zextloadi16 node:$ptr))>; +def zextloadi64i32 : PatFrag<(ops node:$ptr), (i64 (zextloadi32 node:$ptr))>; + + //===----------------------------------------------------------------------===// // SystemZ Operand Definitions. //===----------------------------------------------------------------------===// @@ -200,10 +214,31 @@ def MOV64rihi32 : Pseudo<(outs GR64:$dst), (ins i64imm:$src), let canFoldAsLoad = 1, isReMaterializable = 1, mayHaveSideEffects = 1 in { def MOV64rm : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), - "lgr\t{$dst, $src}", + "lg\t{$dst, $src}", [(set GR64:$dst, (load rriaddr:$src))]>; + } +def MOVSX64rm8 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), + "lgb\t{$dst, $src}", + [(set GR64:$dst, (sextloadi64i8 rriaddr:$src))]>; +def MOVSX64rm16 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), + "lgh\t{$dst, $src}", + [(set GR64:$dst, (sextloadi64i16 rriaddr:$src))]>; +def MOVSX64rm32 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), + "lgf\t{$dst, $src}", + [(set GR64:$dst, (sextloadi64i32 rriaddr:$src))]>; + +def MOVZX64rm8 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), + "llgc\t{$dst, $src}", + [(set GR64:$dst, (zextloadi64i8 rriaddr:$src))]>; +def MOVZX64rm16 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), + "llgh\t{$dst, $src}", + [(set GR64:$dst, (zextloadi64i16 rriaddr:$src))]>; +def MOVZX64rm32 : Pseudo<(outs GR64:$dst), (ins rriaddr:$src), + "llgf\t{$dst, $src}", + [(set GR64:$dst, (zextloadi64i32 rriaddr:$src))]>; + //===----------------------------------------------------------------------===// // Arithmetic Instructions @@ -410,3 +445,8 @@ def : Pat<(i32 (trunc GR64:$src)), // sext_inreg patterns def : Pat<(sext_inreg GR64:$src, i32), (MOVSX64rr32 (EXTRACT_SUBREG GR64:$src, subreg_32bit))>; + +// extload patterns +def : Pat<(extloadi64i8 rriaddr:$src), (MOVZX64rm8 rriaddr:$src)>; +def : Pat<(extloadi64i16 rriaddr:$src), (MOVZX64rm16 rriaddr:$src)>; +def : Pat<(extloadi64i32 rriaddr:$src), (MOVZX64rm32 rriaddr:$src)>; diff --git a/test/CodeGen/SystemZ/05-MemRegLoads.ll b/test/CodeGen/SystemZ/05-MemRegLoads.ll new file mode 100644 index 00000000000..0dc5920ea3f --- /dev/null +++ b/test/CodeGen/SystemZ/05-MemRegLoads.ll @@ -0,0 +1,75 @@ +; RUN: llvm-as < %s | llc -march=systemz | not grep aghi +; RUN: llvm-as < %s | llc -march=systemz | grep llgf | count 1 +; RUN: llvm-as < %s | llc -march=systemz | grep llgh | count 1 +; RUN: llvm-as < %s | llc -march=systemz | grep llgc | count 1 +; RUN: llvm-as < %s | llc -march=systemz | grep lgf | count 2 +; RUN: llvm-as < %s | llc -march=systemz | grep lgh | count 2 +; RUN: llvm-as < %s | llc -march=systemz | grep lgb | count 1 + + +target datalayout = "E-p:64:64:64-i1:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-f128:128:128" +target triple = "s390x-unknown-linux-gnu" + +define zeroext i64 @foo1(i64* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i64* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i64* %add.ptr2 ; [#uses=1] + ret i64 %tmp3 +} + +define zeroext i32 @foo2(i32* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i32* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i32* %add.ptr2 ; [#uses=1] + ret i32 %tmp3 +} + +define zeroext i16 @foo3(i16* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i16* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i16* %add.ptr2 ; [#uses=1] + ret i16 %tmp3 +} + +define zeroext i8 @foo4(i8* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i8* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i8* %add.ptr2 ; [#uses=1] + ret i8 %tmp3 +} + +define signext i64 @foo5(i64* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i64* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i64* %add.ptr2 ; [#uses=1] + ret i64 %tmp3 +} + +define signext i32 @foo6(i32* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i32* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i32* %add.ptr2 ; [#uses=1] + ret i32 %tmp3 +} + +define signext i16 @foo7(i16* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i16* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i16* %add.ptr2 ; [#uses=1] + ret i16 %tmp3 +} + +define signext i8 @foo8(i8* nocapture %a, i64 %idx) nounwind readonly { +entry: + %add.ptr.sum = add i64 %idx, 1 ; [#uses=1] + %add.ptr2 = getelementptr i8* %a, i64 %add.ptr.sum ; [#uses=1] + %tmp3 = load i8* %add.ptr2 ; [#uses=1] + ret i8 %tmp3 +}