[llvm] r188546 - [SystemZ] Use MVST to implement strcpy and stpcpy
Richard Sandiford
rsandifo at linux.vnet.ibm.com
Fri Aug 16 04:29:38 PDT 2013
Author: rsandifo
Date: Fri Aug 16 06:29:37 2013
New Revision: 188546
URL: http://llvm.org/viewvc/llvm-project?rev=188546&view=rev
Log:
[SystemZ] Use MVST to implement strcpy and stpcpy
Added:
llvm/trunk/test/CodeGen/SystemZ/strcpy-01.ll
Modified:
llvm/trunk/include/llvm/Target/TargetLibraryInfo.h
llvm/trunk/include/llvm/Target/TargetSelectionDAGInfo.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
llvm/trunk/lib/Target/SystemZ/SystemZOperators.td
llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt
llvm/trunk/test/MC/SystemZ/insn-good.s
Modified: llvm/trunk/include/llvm/Target/TargetLibraryInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLibraryInfo.h?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLibraryInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLibraryInfo.h Fri Aug 16 06:29:37 2013
@@ -699,7 +699,8 @@ public:
case LibFunc::trunc: case LibFunc::truncf: case LibFunc::truncl:
case LibFunc::log2: case LibFunc::log2f: case LibFunc::log2l:
case LibFunc::exp2: case LibFunc::exp2f: case LibFunc::exp2l:
- case LibFunc::memcmp: case LibFunc::strcmp:
+ case LibFunc::memcmp: case LibFunc::strcmp: case LibFunc::strcpy:
+ case LibFunc::stpcpy:
return true;
}
return false;
Modified: llvm/trunk/include/llvm/Target/TargetSelectionDAGInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetSelectionDAGInfo.h?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetSelectionDAGInfo.h (original)
+++ llvm/trunk/include/llvm/Target/TargetSelectionDAGInfo.h Fri Aug 16 06:29:37 2013
@@ -109,6 +109,21 @@ public:
return std::make_pair(SDValue(), SDValue());
}
+ /// EmitTargetCodeForStrcpy - Emit target-specific code that performs a
+ /// strcpy or stpcpy, in cases where that is faster than a libcall.
+ /// The first returned SDValue is the result of the copy (the start
+ /// of the destination string for strcpy, a pointer to the null terminator
+ /// for stpcpy) and the second is the chain. Both SDValues can be null
+ /// if a normal libcall should be used.
+ virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+ SDValue Dest, SDValue Src,
+ MachinePointerInfo DestPtrInfo,
+ MachinePointerInfo SrcPtrInfo,
+ bool isStpcpy) const {
+ return std::make_pair(SDValue(), SDValue());
+ }
+
/// EmitTargetCodeForStrcmp - Emit target-specific code that performs a
/// strcmp, in cases where that is faster than a libcall. The first
/// returned SDValue is the result of the strcmp and the second is
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp Fri Aug 16 06:29:37 2013
@@ -5558,6 +5558,35 @@ bool SelectionDAGBuilder::visitMemCmpCal
return false;
}
+/// visitStrCpyCall -- See if we can lower a strcpy or stpcpy call into an
+/// optimized form. If so, return true and lower it, otherwise return false
+/// and it will be lowered like a normal call.
+bool SelectionDAGBuilder::visitStrCpyCall(const CallInst &I, bool isStpcpy) {
+ // Verify that the prototype makes sense. char *strcpy(char *, char *)
+ if (I.getNumArgOperands() != 2)
+ return false;
+
+ const Value *Arg0 = I.getArgOperand(0), *Arg1 = I.getArgOperand(1);
+ if (!Arg0->getType()->isPointerTy() ||
+ !Arg1->getType()->isPointerTy() ||
+ !I.getType()->isPointerTy())
+ return false;
+
+ const TargetSelectionDAGInfo &TSI = DAG.getSelectionDAGInfo();
+ std::pair<SDValue, SDValue> Res =
+ TSI.EmitTargetCodeForStrcpy(DAG, getCurSDLoc(), getRoot(),
+ getValue(Arg0), getValue(Arg1),
+ MachinePointerInfo(Arg0),
+ MachinePointerInfo(Arg1), isStpcpy);
+ if (Res.first.getNode()) {
+ setValue(&I, Res.first);
+ DAG.setRoot(Res.second);
+ return true;
+ }
+
+ return false;
+}
+
/// visitStrCmpCall - See if we can lower a call to strcmp in an optimized form.
/// If so, return true and lower it, otherwise return false and it will be
/// lowered like a normal call.
@@ -5733,6 +5762,14 @@ void SelectionDAGBuilder::visitCall(cons
if (visitMemCmpCall(I))
return;
break;
+ case LibFunc::strcpy:
+ if (visitStrCpyCall(I, false))
+ return;
+ break;
+ case LibFunc::stpcpy:
+ if (visitStrCpyCall(I, true))
+ return;
+ break;
case LibFunc::strcmp:
if (visitStrCmpCall(I))
return;
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.h Fri Aug 16 06:29:37 2013
@@ -523,6 +523,7 @@ private:
void visitPHI(const PHINode &I);
void visitCall(const CallInst &I);
bool visitMemCmpCall(const CallInst &I);
+ bool visitStrCpyCall(const CallInst &I, bool isStpcpy);
bool visitStrCmpCall(const CallInst &I);
bool visitUnaryFloatCall(const CallInst &I, unsigned Opcode);
void visitAtomicLoad(const LoadInst &I);
Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.cpp Fri Aug 16 06:29:37 2013
@@ -1703,6 +1703,7 @@ const char *SystemZTargetLowering::getTa
OPCODE(MVC);
OPCODE(CLC);
OPCODE(STRCMP);
+ OPCODE(STPCPY);
OPCODE(IPM);
OPCODE(ATOMIC_SWAPW);
OPCODE(ATOMIC_LOADW_ADD);
@@ -2551,6 +2552,8 @@ EmitInstrWithCustomInserter(MachineInstr
return emitMemMemWrapper(MI, MBB, SystemZ::CLC);
case SystemZ::CLSTLoop:
return emitStringWrapper(MI, MBB, SystemZ::CLST);
+ case SystemZ::MVSTLoop:
+ return emitStringWrapper(MI, MBB, SystemZ::MVST);
default:
llvm_unreachable("Unexpected instr type to insert");
}
Modified: llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZISelLowering.h Fri Aug 16 06:29:37 2013
@@ -84,6 +84,9 @@ namespace SystemZISD {
// as for MVC.
CLC,
+ // Use an MVST-based sequence to implement stpcpy().
+ STPCPY,
+
// Use a CLST-based sequence to implement strcmp(). The two input operands
// are the addresses of the strings to compare.
STRCMP,
Modified: llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZInstrInfo.td Fri Aug 16 06:29:37 2013
@@ -336,6 +336,10 @@ def MVGHI : StoreSIL<"mvghi", 0xE548, st
let mayLoad = 1, mayStore = 1 in
defm MVC : MemorySS<"mvc", 0xD2, z_mvc>;
+// String moves.
+let mayLoad = 1, mayStore = 1, Defs = [CC], Uses = [R0W] in
+ defm MVST : StringRRE<"mvst", 0xB255, z_stpcpy>;
+
defm LoadStore8_32 : MVCLoadStore<anyextloadi8, truncstorei8, i32,
MVCWrapper, 1>;
defm LoadStore16_32 : MVCLoadStore<anyextloadi16, truncstorei16, i32,
Modified: llvm/trunk/lib/Target/SystemZ/SystemZOperators.td
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZOperators.td?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZOperators.td (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZOperators.td Fri Aug 16 06:29:37 2013
@@ -121,6 +121,8 @@ def z_clc : SDNode<"System
[SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>;
def z_strcmp : SDNode<"SystemZISD::STRCMP", SDT_ZString,
[SDNPHasChain, SDNPOutGlue, SDNPMayLoad]>;
+def z_stpcpy : SDNode<"SystemZISD::STPCPY", SDT_ZString,
+ [SDNPHasChain, SDNPMayStore, SDNPMayLoad]>;
def z_ipm : SDNode<"SystemZISD::IPM", SDT_ZI32Intrinsic,
[SDNPInGlue]>;
Modified: llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.cpp Fri Aug 16 06:29:37 2013
@@ -159,6 +159,17 @@ EmitTargetCodeForMemcmp(SelectionDAG &DA
}
std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::
+EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+ SDValue Dest, SDValue Src,
+ MachinePointerInfo DestPtrInfo,
+ MachinePointerInfo SrcPtrInfo, bool isStpcpy) const {
+ SDVTList VTs = DAG.getVTList(Dest.getValueType(), MVT::Other);
+ SDValue EndDest = DAG.getNode(SystemZISD::STPCPY, DL, VTs, Chain, Dest, Src,
+ DAG.getConstant(0, MVT::i32));
+ return std::make_pair(isStpcpy ? EndDest : Dest, EndDest.getValue(1));
+}
+
+std::pair<SDValue, SDValue> SystemZSelectionDAGInfo::
EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
SDValue Src1, SDValue Src2,
MachinePointerInfo Op1PtrInfo,
Modified: llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.h?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.h (original)
+++ llvm/trunk/lib/Target/SystemZ/SystemZSelectionDAGInfo.h Fri Aug 16 06:29:37 2013
@@ -47,6 +47,13 @@ public:
MachinePointerInfo Op2PtrInfo) const LLVM_OVERRIDE;
virtual std::pair<SDValue, SDValue>
+ EmitTargetCodeForStrcpy(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
+ SDValue Dest, SDValue Src,
+ MachinePointerInfo DestPtrInfo,
+ MachinePointerInfo SrcPtrInfo,
+ bool isStpcpy) const LLVM_OVERRIDE;
+
+ virtual std::pair<SDValue, SDValue>
EmitTargetCodeForStrcmp(SelectionDAG &DAG, SDLoc DL, SDValue Chain,
SDValue Src1, SDValue Src2,
MachinePointerInfo Op1PtrInfo,
Added: llvm/trunk/test/CodeGen/SystemZ/strcpy-01.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/SystemZ/strcpy-01.ll?rev=188546&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/SystemZ/strcpy-01.ll (added)
+++ llvm/trunk/test/CodeGen/SystemZ/strcpy-01.ll Fri Aug 16 06:29:37 2013
@@ -0,0 +1,50 @@
+; Test strcpy using MVST.
+;
+; RUN: llc < %s -mtriple=s390x-linux-gnu | FileCheck %s
+
+declare i8 *@strcpy(i8 *%dest, i8 *%src)
+declare i8 *@stpcpy(i8 *%dest, i8 *%src)
+
+; Check strcpy.
+define i8 *@f1(i8 *%dest, i8 *%src) {
+; CHECK-LABEL: f1:
+; CHECK-DAG: lhi %r0, 0
+; CHECK-DAG: lgr [[REG:%r[145]]], %r2
+; CHECK: [[LABEL:\.[^:]*]]:
+; CHECK-NEXT: mvst [[REG]], %r3
+; CHECK-NEXT: jo [[LABEL]]
+; CHECK-NOT: %r2
+; CHECK: br %r14
+ %res = call i8 *@strcpy(i8 *%dest, i8 *%src)
+ ret i8 *%res
+}
+
+; Check stpcpy.
+define i8 *@f2(i8 *%dest, i8 *%src) {
+; CHECK-LABEL: f2:
+; CHECK: lhi %r0, 0
+; CHECK: [[LABEL:\.[^:]*]]:
+; CHECK-NEXT: mvst %r2, %r3
+; CHECK-NEXT: jo [[LABEL]]
+; CHECK-NOT: %r2
+; CHECK: br %r14
+ %res = call i8 *@stpcpy(i8 *%dest, i8 *%src)
+ ret i8 *%res
+}
+
+; Check correct operation with other loads and stores. The load must
+; come before the loop and the store afterwards.
+define i32 @f3(i32 %dummy, i8 *%dest, i8 *%src, i32 *%resptr, i32 *%storeptr) {
+; CHECK-LABEL: f3:
+; CHECK-DAG: lhi %r0, 0
+; CHECK-DAG: l %r2, 0(%r5)
+; CHECK: [[LABEL:\.[^:]*]]:
+; CHECK-NEXT: mvst %r3, %r4
+; CHECK-NEXT: jo [[LABEL]]
+; CHECK: mvhi 0(%r6), 0
+; CHECK: br %r14
+ %res = load i32 *%resptr
+ %unused = call i8 *@strcpy(i8 *%dest, i8 *%src)
+ store i32 0, i32 *%storeptr
+ ret i32 %res
+}
Modified: llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt (original)
+++ llvm/trunk/test/MC/Disassembler/SystemZ/insns.txt Fri Aug 16 06:29:37 2013
@@ -4678,6 +4678,18 @@
# CHECK: mviy 524287(%r15), 42
0xeb 0x2a 0xff 0xff 0x7f 0x52
+# CHECK: mvst %r0, %r0
+0xb2 0x55 0x00 0x00
+
+# CHECK: mvst %r0, %r15
+0xb2 0x55 0x00 0x0f
+
+# CHECK: mvst %r15, %r0
+0xb2 0x55 0x00 0xf0
+
+# CHECK: mvst %r7, %r8
+0xb2 0x55 0x00 0x78
+
# CHECK: mxbr %f0, %f0
0xb3 0x4c 0x00 0x00
Modified: llvm/trunk/test/MC/SystemZ/insn-good.s
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/MC/SystemZ/insn-good.s?rev=188546&r1=188545&r2=188546&view=diff
==============================================================================
--- llvm/trunk/test/MC/SystemZ/insn-good.s (original)
+++ llvm/trunk/test/MC/SystemZ/insn-good.s Fri Aug 16 06:29:37 2013
@@ -5652,6 +5652,16 @@
mviy 524287(%r1), 42
mviy 524287(%r15), 42
+#CHECK: mvst %r0, %r0 # encoding: [0xb2,0x55,0x00,0x00]
+#CHECK: mvst %r0, %r15 # encoding: [0xb2,0x55,0x00,0x0f]
+#CHECK: mvst %r15, %r0 # encoding: [0xb2,0x55,0x00,0xf0]
+#CHECK: mvst %r7, %r8 # encoding: [0xb2,0x55,0x00,0x78]
+
+ mvst %r0,%r0
+ mvst %r0,%r15
+ mvst %r15,%r0
+ mvst %r7,%r8
+
#CHECK: mxbr %f0, %f0 # encoding: [0xb3,0x4c,0x00,0x00]
#CHECK: mxbr %f0, %f13 # encoding: [0xb3,0x4c,0x00,0x0d]
#CHECK: mxbr %f8, %f5 # encoding: [0xb3,0x4c,0x00,0x85]
More information about the llvm-commits
mailing list