Index: lib/Target/X86/X86ISelLowering.cpp =================================================================== --- lib/Target/X86/X86ISelLowering.cpp +++ lib/Target/X86/X86ISelLowering.cpp @@ -2833,7 +2833,7 @@ if (Flags.isByVal()) { unsigned Bytes = Flags.getByValSize(); if (Bytes == 0) Bytes = 1; // Don't create zero-sized stack objects. - int FI = MFI.CreateFixedObject(Bytes, VA.getLocMemOffset(), isImmutable); + int FI = MFI.CreateFixedObject(Bytes, VA.getLocMemOffset(), isImmutable, true); // Adjust SP offset of interrupt parameter. if (CallConv == CallingConv::X86_INTR) { MFI.setObjectOffset(FI, Offset); Index: test/CodeGen/X86/pr30290.ll =================================================================== --- /dev/null +++ test/CodeGen/X86/pr30290.ll @@ -0,0 +1,86 @@ +; RUN: lli -mcpu=btver2 %s | FileCheck %s +; CHECK: 5 +; Test desc: two functions (foo, bar) with byval arguments, should not have +; reads/writes from/to byval storage re-ordered. +source_filename = "test.c" +target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128" +target triple = "x86_64-pc-linux-gnu" + +%struct.face = type { [7 x i32] } + +@.str = private unnamed_addr constant [4 x i8] c"%d\0A\00", align 1 + +; Function Attrs: noinline nounwind uwtable +define void @baz(%struct.face* byval nocapture readonly align 8) local_unnamed_addr #0 { + %2 = getelementptr inbounds %struct.face, %struct.face* %0, i64 0, i32 0, i64 0 + %3 = load i32, i32* %2, align 8, !tbaa !2 + %4 = getelementptr inbounds %struct.face, %struct.face* %0, i64 0, i32 0, i64 1 + %5 = load i32, i32* %4, align 4, !tbaa !2 + %6 = getelementptr inbounds %struct.face, %struct.face* %0, i64 0, i32 0, i64 2 + %7 = load i32, i32* %6, align 8, !tbaa !2 + %8 = getelementptr inbounds %struct.face, %struct.face* %0, i64 0, i32 0, i64 3 + %9 = bitcast i32* %8 to <4 x i32>* + %10 = load <4 x i32>, <4 x i32>* %9, align 4, !tbaa !2 + %11 = shufflevector <4 x i32> %10, <4 x i32> undef, <4 x i32> + %12 = add nsw <4 x i32> %10, %11 + %13 = shufflevector <4 x i32> %12, <4 x i32> undef, <4 x i32> + %14 = add nsw <4 x i32> %12, %13 + %15 = extractelement <4 x i32> %14, i32 0 + %16 = add nsw i32 %15, %7 + %17 = add nsw i32 %16, %5 + %18 = add nsw i32 %17, %3 + %19 = tail call i32 (i8*, ...) @printf(i8* getelementptr inbounds ([4 x i8], [4 x i8]* @.str, i64 0, i64 0), i32 %18) + ret void +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) #1 + +; Function Attrs: argmemonly nounwind +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) #1 + +; Function Attrs: nounwind +declare i32 @printf(i8* nocapture readonly, ...) local_unnamed_addr #2 + +; Function Attrs: noinline nounwind uwtable +define void @foo(%struct.face* byval nocapture align 8) local_unnamed_addr #0 { + %2 = bitcast %struct.face* %0 to <4 x i32>* + store <4 x i32> , <4 x i32>* %2, align 8, !tbaa !2 + %3 = getelementptr inbounds %struct.face, %struct.face* %0, i64 0, i32 0, i64 4 + store i32 1, i32* %3, align 8, !tbaa !2 +; XXX XXX XXX +; Fault happens here: five "1" constants have just been written into the byval +; %struct.face, but the subsequent byval read of that struct (next call) +; gets re-ordered with those writes, illegally. + call void @baz(%struct.face* byval nonnull align 8 %0) + ret void +} + +; Function Attrs: noinline nounwind uwtable +define i32 @main() local_unnamed_addr #0 { + %1 = alloca %struct.face, align 8 + %2 = bitcast %struct.face* %1 to i8* + call void @llvm.lifetime.start.p0i8(i64 28, i8* nonnull %2) #3 + call void @llvm.memset.p0i8.i64(i8* nonnull %2, i8 0, i64 28, i32 8, i1 false) + call void @foo(%struct.face* byval nonnull align 8 %1) + call void @llvm.lifetime.end.p0i8(i64 28, i8* nonnull %2) #3 + ret i32 0 +} + +; Function Attrs: argmemonly nounwind +declare void @llvm.memset.p0i8.i64(i8* nocapture writeonly, i8, i64, i32, i1) #1 + +attributes #0 = { noinline nounwind uwtable "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="btver2" "target-features"="+aes,+avx,+bmi,+cx16,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #1 = { argmemonly nounwind } +attributes #2 = { nounwind "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "no-frame-pointer-elim"="false" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="btver2" "target-features"="+aes,+avx,+bmi,+cx16,+f16c,+fxsr,+lzcnt,+mmx,+movbe,+pclmul,+popcnt,+prfchw,+sse,+sse2,+sse3,+sse4.1,+sse4.2,+sse4a,+ssse3,+x87,+xsave,+xsaveopt" "unsafe-fp-math"="false" "use-soft-float"="false" } +attributes #3 = { nounwind } + +!llvm.module.flags = !{!0} +!llvm.ident = !{!1} + +!0 = !{i32 1, !"wchar_size", i32 4} +!1 = !{!"clang version 6.0.0-svn326550-1~exp1~20180404173613.65 (branches/release_60)"} +!2 = !{!3, !3, i64 0} +!3 = !{!"int", !4, i64 0} +!4 = !{!"omnipotent char", !5, i64 0} +!5 = !{!"Simple C/C++ TBAA"}