LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 19012 - [MS ABI] Bad interaction between inalloca call and expanded memcpy
Summary: [MS ABI] Bad interaction between inalloca call and expanded memcpy
Status: RESOLVED FIXED
Alias: None
Product: clang
Classification: Unclassified
Component: -New Bugs (show other bugs)
Version: unspecified
Hardware: PC Windows NT
: P normal
Assignee: Hans Wennborg
URL:
Keywords:
Depends on:
Blocks: 12477 18887
  Show dependency tree
 
Reported: 2014-02-28 19:50 PST by Hans Wennborg
Modified: 2014-08-29 15:51 PDT (History)
2 users (show)

See Also:
Fixed By Commit(s):


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Hans Wennborg 2014-02-28 19:50:57 PST
The following program crashes when built with clang-cl:

(If the #if 1 is changed to #if 0, it doesn't crash. For some reason that causes us not to expand the memcpy.)

struct Ptr {
  ~Ptr() {}
  int *ptr;
};

#if 1
struct Arr {
  struct {
    struct {
      char name[54];
    } mailbox;
    int texture_target;
    int sync_point;
  } mailbox_holder;
  void *shared_memory;
  struct shared_memory_size {
    int width;
    int height;
  } memory_size;
};
#else
struct Arr {
  char x[76];
};
#endif

void f(Ptr) {}

void g(Arr *a, Arr *b, Ptr *p) {
  *a = *b; // memcpy, possibly expanded to rep movs, clobbering esi
  f(*p);   // inalloca call, causing chkstk, not expecting clobbered esi
};

int main() {
  Ptr p = {};
  Arr a = {}, b = {};
  g(&a, &b, &p);
  return 0;
}

(Reduced from Chromium's cc::CopyOutputResult::TakeTexture.)
Comment 1 Hans Wennborg 2014-03-03 13:31:44 PST
Slightly reduced:

$ llc -mcpu=pentium4 a.ll -o -

a.ll:

target datalayout = "e-m:w-p:32:32-i64:64-f80:32-n8:16:32-S32"
target triple = "i686-pc-win32"

%struct.Ptr = type { i32* }
%struct.Arr = type { %struct.anon, i8*, %"struct.Arr::shared_memory_size" }
%struct.anon = type { %struct.anon.0, i32, i32 }
%struct.anon.0 = type { [54 x i8] }
%"struct.Arr::shared_memory_size" = type { i32, i32 }

declare void @llvm.memcpy.p0i8.p0i8.i32(i8* nocapture, i8* nocapture readonly, i32, i32, i1)
declare i8* @llvm.stacksave()
declare void @llvm.stackrestore(i8*)
declare void @f(<{ %struct.Ptr }>* inalloca) #0

define void @g(%struct.Arr* %a, %struct.Arr* %b, %struct.Ptr* %p) #0 {
entry:
  %inalloca.spmem = alloca i8*
  %aptr = bitcast %struct.Arr* %a to i8*
  %bptr = bitcast %struct.Arr* %b to i8*
  %pptr = bitcast %struct.Ptr* %p to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %aptr, i8* %bptr, i32 76, i32 4, i1 false)
  %inalloca.save = call i8* @llvm.stacksave()
  %argmem = alloca <{ %struct.Ptr }>, inalloca
  store i8* %inalloca.save, i8** %inalloca.spmem
  %gep = getelementptr inbounds <{ %struct.Ptr }>* %argmem, i32 0, i32 0
  %gepptr = bitcast %struct.Ptr* %gep to i8*
  call void @llvm.memcpy.p0i8.p0i8.i32(i8* %gepptr, i8* %pptr, i32 4, i32 4, i1 false)
  call void @f(<{ %struct.Ptr }>* inalloca %argmem)
  call void @llvm.stackrestore(i8* %inalloca.save)
  ret void
}
Comment 2 Hans Wennborg 2014-03-04 20:46:48 PST
Should be fixed with r202930.
Comment 3 Reid Kleckner 2014-08-29 15:51:11 PDT
Hopefully fixed harder in r216775.