Skip to content

Commit a5b0e55

Browse files
author
Serguei Katkov
committed
[InstCombine]Avoid introduction of unaligned mem access
InstCombine is able to transform mem transfer instrinsic to alone store or store/load pair. It might result in generation of unaligned atomic load/store which later in backend will be transformed to libcall. It is not an evident gain and it is better to keep intrinsic as is and handle it at backend. Reviewers: reames, anna, apilipenko, mkazantsev Reviewed By: reames Subscribers: t.p.northover, jfb, llvm-commits Differential Revision: https://reviews.llvm.org/D56582 llvm-svn: 351295
1 parent 8e92050 commit a5b0e55

File tree

2 files changed

+178
-93
lines changed

2 files changed

+178
-93
lines changed

llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp

+20-3
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,14 @@ Instruction *InstCombiner::SimplifyAnyMemTransfer(AnyMemTransferInst *MI) {
136136
if (Size > 8 || (Size&(Size-1)))
137137
return nullptr; // If not 1/2/4/8 bytes, exit.
138138

139+
// If it is an atomic and alignment is less than the size then we will
140+
// introduce the unaligned memory access which will be later transformed
141+
// into libcall in CodeGen. This is not evident performance gain so disable
142+
// it now.
143+
if (isa<AtomicMemTransferInst>(MI))
144+
if (CopyDstAlign < Size || CopySrcAlign < Size)
145+
return nullptr;
146+
139147
// Use an integer load+store unless we can find something better.
140148
unsigned SrcAddrSp =
141149
cast<PointerType>(MI->getArgOperand(1)->getType())->getAddressSpace();
@@ -220,6 +228,18 @@ Instruction *InstCombiner::SimplifyAnyMemSet(AnyMemSetInst *MI) {
220228
Alignment = MI->getDestAlignment();
221229
assert(Len && "0-sized memory setting should be removed already.");
222230

231+
// Alignment 0 is identity for alignment 1 for memset, but not store.
232+
if (Alignment == 0)
233+
Alignment = 1;
234+
235+
// If it is an atomic and alignment is less than the size then we will
236+
// introduce the unaligned memory access which will be later transformed
237+
// into libcall in CodeGen. This is not evident performance gain so disable
238+
// it now.
239+
if (isa<AtomicMemSetInst>(MI))
240+
if (Alignment < Len)
241+
return nullptr;
242+
223243
// memset(s,c,n) -> store s, c (for n=1,2,4,8)
224244
if (Len <= 8 && isPowerOf2_32((uint32_t)Len)) {
225245
Type *ITy = IntegerType::get(MI->getContext(), Len*8); // n=1 -> i8.
@@ -229,9 +249,6 @@ Instruction *InstCombiner::SimplifyAnyMemSet(AnyMemSetInst *MI) {
229249
Type *NewDstPtrTy = PointerType::get(ITy, DstAddrSp);
230250
Dest = Builder.CreateBitCast(Dest, NewDstPtrTy);
231251

232-
// Alignment 0 is identity for alignment 1 for memset, but not store.
233-
if (Alignment == 0) Alignment = 1;
234-
235252
// Extract the fill value and store.
236253
uint64_t Fill = FillC->getZExtValue()*0x0101010101010101ULL;
237254
StoreInst *S = Builder.CreateStore(ConstantInt::get(ITy, Fill), Dest,

0 commit comments

Comments
 (0)