[llvm-commits] [llvm] r100208 - in /llvm/trunk: include/llvm/Target/TargetLowering.h lib/CodeGen/SelectionDAG/SelectionDAG.cpp lib/Target/PowerPC/PPCISelLowering.cpp lib/Target/PowerPC/PPCISelLowering.h lib/Target/X86/X86ISelLowering.cpp lib/Target/X86/X86ISelLowering.h test/CodeGen/X86/memset-2.ll test/CodeGen/X86/memset-3.ll
Evan Cheng
evan.cheng at apple.com
Fri Apr 2 12:36:14 PDT 2010
Author: evancheng
Date: Fri Apr 2 14:36:14 2010
New Revision: 100208
URL: http://llvm.org/viewvc/llvm-project?rev=100208&view=rev
Log:
Correctly lower memset / memcpy of undef. It should be a nop. PR6767.
Added:
llvm/trunk/test/CodeGen/X86/memset-3.ll
Modified:
llvm/trunk/include/llvm/Target/TargetLowering.h
llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
llvm/trunk/lib/Target/X86/X86ISelLowering.h
llvm/trunk/test/CodeGen/X86/memset-2.ll
Modified: llvm/trunk/include/llvm/Target/TargetLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/Target/TargetLowering.h?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/include/llvm/Target/TargetLowering.h (original)
+++ llvm/trunk/include/llvm/Target/TargetLowering.h Fri Apr 2 14:36:14 2010
@@ -633,15 +633,19 @@
}
/// getOptimalMemOpType - Returns the target specific optimal type for load
- /// and store operations as a result of memset, memcpy, and memmove lowering.
- /// If DstAlign is zero that means it's safe to destination alignment can
- /// satisfy any constraint. Similarly if SrcAlign is zero it means there isn't
- /// a need to check it against alignment requirement, probably because the
- /// source does not need to be loaded. It returns EVT::Other if SelectionDAG
- /// should be responsible for determining it.
+ /// and store operations as a result of memset, memcpy, and memmove
+ /// lowering. If DstAlign is zero that means it's safe to destination
+ /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
+ /// means there isn't a need to check it against alignment requirement,
+ /// probably because the source does not need to be loaded. If
+ /// 'NonScalarIntSafe' is true, that means it's safe to return a
+ /// non-scalar-integer type, e.g. empty string source, constant, or loaded
+ /// from memory. It returns EVT::Other if SelectionDAG should be responsible
+ /// for determining it.
virtual EVT getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool SafeToUseFP, SelectionDAG &DAG) const {
+ bool NonScalarIntSafe,
+ SelectionDAG &DAG) const {
return MVT::Other;
}
Modified: llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp (original)
+++ llvm/trunk/lib/CodeGen/SelectionDAG/SelectionDAG.cpp Fri Apr 2 14:36:14 2010
@@ -3094,6 +3094,8 @@
/// operand.
static SDValue getMemsetValue(SDValue Value, EVT VT, SelectionDAG &DAG,
DebugLoc dl) {
+ assert(Value.getOpcode() != ISD::UNDEF);
+
unsigned NumBits = VT.getScalarType().getSizeInBits();
if (ConstantSDNode *C = dyn_cast<ConstantSDNode>(Value)) {
APInt Val = APInt(NumBits, C->getZExtValue() & 255);
@@ -3197,7 +3199,7 @@
static bool FindOptimalMemOpLowering(std::vector<EVT> &MemOps,
unsigned Limit, uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool SafeToUseFP,
+ bool NonScalarIntSafe,
SelectionDAG &DAG,
const TargetLowering &TLI) {
assert((SrcAlign == 0 || SrcAlign >= DstAlign) &&
@@ -3207,7 +3209,8 @@
// the inferred alignment of the source. 'DstAlign', on the other hand, is the
// specified alignment of the memory operation. If it is zero, that means
// it's possible to change the alignment of the destination.
- EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign, SafeToUseFP, DAG);
+ EVT VT = TLI.getOptimalMemOpType(Size, DstAlign, SrcAlign,
+ NonScalarIntSafe, DAG);
if (VT == MVT::Other) {
VT = TLI.getPointerTy();
@@ -3266,10 +3269,13 @@
unsigned Align, bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ // Turn a memcpy of undef to nop.
+ if (Src.getOpcode() == ISD::UNDEF)
+ return Chain;
// Expand memcpy to a series of load and store ops if the size operand falls
// below a certain threshold.
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::vector<EVT> MemOps;
uint64_t Limit = -1ULL;
if (!AlwaysInline)
@@ -3352,10 +3358,13 @@
unsigned Align,bool AlwaysInline,
const Value *DstSV, uint64_t DstSVOff,
const Value *SrcSV, uint64_t SrcSVOff) {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ // Turn a memmove of undef to nop.
+ if (Src.getOpcode() == ISD::UNDEF)
+ return Chain;
// Expand memmove to a series of load and store ops if the size operand falls
// below a certain threshold.
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::vector<EVT> MemOps;
uint64_t Limit = -1ULL;
if (!AlwaysInline)
@@ -3426,21 +3435,24 @@
SDValue Src, uint64_t Size,
unsigned Align,
const Value *DstSV, uint64_t DstSVOff) {
- const TargetLowering &TLI = DAG.getTargetLoweringInfo();
+ // Turn a memset of undef to nop.
+ if (Src.getOpcode() == ISD::UNDEF)
+ return Chain;
// Expand memset to a series of load/store ops if the size operand
// falls below a certain threshold.
+ const TargetLowering &TLI = DAG.getTargetLoweringInfo();
std::vector<EVT> MemOps;
bool DstAlignCanChange = false;
MachineFrameInfo *MFI = DAG.getMachineFunction().getFrameInfo();
FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Dst);
if (FI && !MFI->isFixedObjectIndex(FI->getIndex()))
DstAlignCanChange = true;
- bool IsZero = isa<ConstantSDNode>(Src) &&
- cast<ConstantSDNode>(Src)->isNullValue();
+ bool NonScalarIntSafe =
+ isa<ConstantSDNode>(Src) && cast<ConstantSDNode>(Src)->isNullValue();
if (!FindOptimalMemOpLowering(MemOps, TLI.getMaxStoresPerMemset(),
Size, (DstAlignCanChange ? 0 : Align), 0,
- IsZero, DAG, TLI))
+ NonScalarIntSafe, DAG, TLI))
return SDValue();
if (DstAlignCanChange) {
@@ -3592,9 +3604,9 @@
if (ConstantSize->isNullValue())
return Chain;
- SDValue Result =
- getMemsetStores(*this, dl, Chain, Dst, Src, ConstantSize->getZExtValue(),
- Align, DstSV, DstSVOff);
+ SDValue Result = getMemsetStores(*this, dl, Chain, Dst, Src,
+ ConstantSize->getZExtValue(),
+ Align, DstSV, DstSVOff);
if (Result.getNode())
return Result;
}
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.cpp Fri Apr 2 14:36:14 2010
@@ -5540,15 +5540,18 @@
}
/// getOptimalMemOpType - Returns the target specific optimal type for load
-/// and store operations as a result of memset, memcpy, and memmove lowering.
-/// If DstAlign is zero that means it's safe to destination alignment can
-/// satisfy any constraint. Similarly if SrcAlign is zero it means there
-/// isn't a need to check it against alignment requirement, probably because
-/// the source does not need to be loaded. It returns EVT::Other if
-/// SelectionDAG should be responsible for determining it.
+/// and store operations as a result of memset, memcpy, and memmove
+/// lowering. If DstAlign is zero that means it's safe to destination
+/// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
+/// means there isn't a need to check it against alignment requirement,
+/// probably because the source does not need to be loaded. If
+/// 'NonScalarIntSafe' is true, that means it's safe to return a
+/// non-scalar-integer type, e.g. empty string source, constant, or loaded
+/// from memory. It returns EVT::Other if SelectionDAG should be responsible
+/// for determining it.
EVT PPCTargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool SafeToUseFP,
+ bool NonScalarIntSafe,
SelectionDAG &DAG) const {
if (this->PPCSubTarget.isPPC64()) {
return MVT::i64;
Modified: llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h (original)
+++ llvm/trunk/lib/Target/PowerPC/PPCISelLowering.h Fri Apr 2 14:36:14 2010
@@ -348,15 +348,19 @@
virtual bool isOffsetFoldingLegal(const GlobalAddressSDNode *GA) const;
/// getOptimalMemOpType - Returns the target specific optimal type for load
- /// and store operations as a result of memset, memcpy, and memmove lowering.
- /// If DstAlign is zero that means it's safe to destination alignment can
- /// satisfy any constraint. Similarly if SrcAlign is zero it means there
- /// isn't a need to check it against alignment requirement, probably because
- /// the source does not need to be loaded. It returns EVT::Other if
- /// SelectionDAG should be responsible for determining it.
- virtual EVT getOptimalMemOpType(uint64_t Size,
- unsigned DstAlign, unsigned SrcAlign,
- bool SafeToUseFP, SelectionDAG &DAG) const;
+ /// and store operations as a result of memset, memcpy, and memmove
+ /// lowering. If DstAlign is zero that means it's safe to destination
+ /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
+ /// means there isn't a need to check it against alignment requirement,
+ /// probably because the source does not need to be loaded. If
+ /// 'NonScalarIntSafe' is true, that means it's safe to return a
+ /// non-scalar-integer type, e.g. empty string source, constant, or loaded
+ /// from memory. It returns EVT::Other if SelectionDAG should be responsible
+ /// for determining it.
+ virtual EVT
+ getOptimalMemOpType(uint64_t Size,
+ unsigned DstAlign, unsigned SrcAlign,
+ bool NonScalarIntSafe, SelectionDAG &DAG) const;
/// getFunctionAlignment - Return the Log2 alignment of this function.
virtual unsigned getFunctionAlignment(const Function *F) const;
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.cpp?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.cpp (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.cpp Fri Apr 2 14:36:14 2010
@@ -1071,18 +1071,21 @@
/// If DstAlign is zero that means it's safe to destination alignment can
/// satisfy any constraint. Similarly if SrcAlign is zero it means there
/// isn't a need to check it against alignment requirement, probably because
-/// the source does not need to be loaded. It returns EVT::Other if
-/// SelectionDAG should be responsible for determining it.
+/// the source does not need to be loaded. If 'NonScalarIntSafe' is true, that
+/// means it's safe to return a non-scalar-integer type, e.g. constant string
+/// source or loaded from memory. It returns EVT::Other if SelectionDAG should
+/// be responsible for determining it.
EVT
X86TargetLowering::getOptimalMemOpType(uint64_t Size,
unsigned DstAlign, unsigned SrcAlign,
- bool SafeToUseFP,
+ bool NonScalarIntSafe,
SelectionDAG &DAG) const {
// FIXME: This turns off use of xmm stores for memset/memcpy on targets like
// linux. This is because the stack realignment code can't handle certain
// cases like PR2962. This should be removed when PR2962 is fixed.
const Function *F = DAG.getMachineFunction().getFunction();
- if (!F->hasFnAttr(Attribute::NoImplicitFloat)) {
+ if (NonScalarIntSafe &&
+ !F->hasFnAttr(Attribute::NoImplicitFloat)) {
if (Size >= 16 &&
(Subtarget->isUnalignedMemAccessFast() ||
((DstAlign == 0 || DstAlign >= 16) &&
@@ -1090,10 +1093,9 @@
Subtarget->getStackAlignment() >= 16) {
if (Subtarget->hasSSE2())
return MVT::v4i32;
- if (SafeToUseFP && Subtarget->hasSSE1())
+ if (Subtarget->hasSSE1())
return MVT::v4f32;
- } else if (SafeToUseFP &&
- Size >= 8 &&
+ } else if (Size >= 8 &&
!Subtarget->is64Bit() &&
Subtarget->getStackAlignment() >= 8 &&
Subtarget->hasSSE2())
Modified: llvm/trunk/lib/Target/X86/X86ISelLowering.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/X86/X86ISelLowering.h?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/lib/Target/X86/X86ISelLowering.h (original)
+++ llvm/trunk/lib/Target/X86/X86ISelLowering.h Fri Apr 2 14:36:14 2010
@@ -417,15 +417,19 @@
virtual unsigned getByValTypeAlignment(const Type *Ty) const;
/// getOptimalMemOpType - Returns the target specific optimal type for load
- /// and store operations as a result of memset, memcpy, and memmove lowering.
- /// If DstAlign is zero that means it's safe to destination alignment can
- /// satisfy any constraint. Similarly if SrcAlign is zero it means there
- /// isn't a need to check it against alignment requirement, probably because
- /// the source does not need to be loaded. It returns EVT::Other if
- /// SelectionDAG should be responsible for determining it.
- virtual EVT getOptimalMemOpType(uint64_t Size,
- unsigned DstAlign, unsigned SrcAlign,
- bool SafeToUseFP, SelectionDAG &DAG) const;
+ /// and store operations as a result of memset, memcpy, and memmove
+ /// lowering. If DstAlign is zero that means it's safe to destination
+ /// alignment can satisfy any constraint. Similarly if SrcAlign is zero it
+ /// means there isn't a need to check it against alignment requirement,
+ /// probably because the source does not need to be loaded. If
+ /// 'NonScalarIntSafe' is true, that means it's safe to return a
+ /// non-scalar-integer type, e.g. empty string source, constant, or loaded
+ /// from memory. It returns EVT::Other if SelectionDAG should be responsible
+ /// for determining it.
+ virtual EVT
+ getOptimalMemOpType(uint64_t Size,
+ unsigned DstAlign, unsigned SrcAlign,
+ bool NonScalarIntSafe, SelectionDAG &DAG) const;
/// allowsUnalignedMemoryAccesses - Returns true if the target allows
/// unaligned memory accesses. of the specified type.
Modified: llvm/trunk/test/CodeGen/X86/memset-2.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-2.ll?rev=100208&r1=100207&r2=100208&view=diff
==============================================================================
--- llvm/trunk/test/CodeGen/X86/memset-2.ll (original)
+++ llvm/trunk/test/CodeGen/X86/memset-2.ll Fri Apr 2 14:36:14 2010
@@ -1,13 +1,11 @@
-; RUN: llc < %s | FileCheck %s
-
-target triple = "i386"
+; RUN: llc -mtriple=i386-apple-darwin < %s | FileCheck %s
declare void @llvm.memset.i32(i8*, i8, i32, i32) nounwind
define fastcc void @t1() nounwind {
entry:
; CHECK: t1:
-; CHECK: call memset
+; CHECK: call _memset
call void @llvm.memset.i32( i8* null, i8 0, i32 188, i32 1 ) nounwind
unreachable
}
@@ -15,7 +13,7 @@
define fastcc void @t2(i8 signext %c) nounwind {
entry:
; CHECK: t2:
-; CHECK: call memset
+; CHECK: call _memset
call void @llvm.memset.i32( i8* undef, i8 %c, i32 76, i32 1 ) nounwind
unreachable
}
Added: llvm/trunk/test/CodeGen/X86/memset-3.ll
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/CodeGen/X86/memset-3.ll?rev=100208&view=auto
==============================================================================
--- llvm/trunk/test/CodeGen/X86/memset-3.ll (added)
+++ llvm/trunk/test/CodeGen/X86/memset-3.ll Fri Apr 2 14:36:14 2010
@@ -0,0 +1,12 @@
+; RUN: llc -mtriple=i386-apple-darwin < %s | not grep memset
+; PR6767
+
+define void @t() nounwind ssp {
+entry:
+ %buf = alloca [512 x i8], align 1
+ %ptr = getelementptr inbounds [512 x i8]* %buf, i32 0, i32 0
+ call void @llvm.memset.i32(i8* %ptr, i8 undef, i32 512, i32 1)
+ unreachable
+}
+
+declare void @llvm.memset.i32(i8* nocapture, i8, i32, i32) nounwind
More information about the llvm-commits
mailing list