Index: llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp =================================================================== --- llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp +++ llvm/trunk/lib/Transforms/Instrumentation/MemorySanitizer.cpp @@ -3131,13 +3131,13 @@ /// \brief AArch64-specific implementation of VarArgHelper. struct VarArgAArch64Helper : public VarArgHelper { - static const unsigned kAArch64GrArgSize = 56; + static const unsigned kAArch64GrArgSize = 64; static const unsigned kAArch64VrArgSize = 128; static const unsigned AArch64GrBegOffset = 0; static const unsigned AArch64GrEndOffset = kAArch64GrArgSize; // Make VR space aligned to 16 bytes. - static const unsigned AArch64VrBegOffset = AArch64GrEndOffset + 8; + static const unsigned AArch64VrBegOffset = AArch64GrEndOffset; static const unsigned AArch64VrEndOffset = AArch64VrBegOffset + kAArch64VrArgSize; static const unsigned AArch64VAEndOffset = AArch64VrEndOffset; @@ -3182,9 +3182,11 @@ unsigned OverflowOffset = AArch64VAEndOffset; const DataLayout &DL = F.getParent()->getDataLayout(); - for (CallSite::arg_iterator ArgIt = CS.arg_begin() + 1, End = CS.arg_end(); + for (CallSite::arg_iterator ArgIt = CS.arg_begin(), End = CS.arg_end(); ArgIt != End; ++ArgIt) { Value *A = *ArgIt; + unsigned ArgNo = CS.getArgumentNo(ArgIt); + bool IsFixed = ArgNo < CS.getFunctionType()->getNumParams(); ArgKind AK = classifyArgument(A); if (AK == AK_GeneralPurpose && GrOffset >= AArch64GrEndOffset) AK = AK_Memory; @@ -3201,11 +3203,19 @@ VrOffset += 16; break; case AK_Memory: + // Don't count fixed arguments in the overflow area - va_start will + // skip right over them. + if (IsFixed) + continue; uint64_t ArgSize = DL.getTypeAllocSize(A->getType()); Base = getShadowPtrForVAArgument(A->getType(), IRB, OverflowOffset); OverflowOffset += alignTo(ArgSize, 8); break; } + // Count Gp/Vr fixed arguments to their respective offsets, but don't + // bother to actually store a shadow. + if (IsFixed) + continue; IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment); } Constant *OverflowSize = Index: llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll =================================================================== --- llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll +++ llvm/trunk/test/Instrumentation/MemorySanitizer/AArch64/vararg.ll @@ -16,8 +16,8 @@ } ; First check if the variadic shadow values are saved in stack with correct -; size (192 is total of general purpose registers size, 56, rounded to 16 -; plus total of floating-point registers size, 128). +; size (192 is total of general purpose registers size, 64, plus total of +; floating-point registers size, 128). ; CHECK-LABEL: @foo ; CHECK: [[A:%.*]] = load {{.*}} @__msan_va_arg_overflow_size_tls @@ -31,7 +31,7 @@ ; offset in the __msan_va_arg_tls based on va_list:__gp_off, and finally ; issue the memcpy. ; CHECK: [[GRP:%.*]] = getelementptr inbounds i8, i8* {{%.*}}, i64 {{%.*}} -; CHECK: [[GRSIZE:%.*]] = sub i64 56, {{%.*}} +; CHECK: [[GRSIZE:%.*]] = sub i64 64, {{%.*}} ; CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(i8* {{%.*}}, i8* [[GRP]], i64 [[GRSIZE]], i32 8, i1 false) ; Propagate the VR shadow values on for the va_list::__vr_top, adjust the @@ -59,17 +59,18 @@ } ; Save the incoming shadow value from the arguments in the __msan_va_arg_tls -; array. General purpose registers are saved at positions from 0 to 56, Floating +; array. General purpose registers are saved at positions from 0 to 64, Floating ; point and SIMD are saved from 64 to 192, and the remaining from 192. ; CHECK-LABEL: @bar ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 8 +; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 16 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 64 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 80 -; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 16 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 24 -; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 96 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 32 +; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 96 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 40 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 48 +; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 56 ; CHECK: store {{.*}} @__msan_va_arg_tls {{.*}} 192 ; CHECK: store {{.*}} 8, {{.*}} @__msan_va_arg_overflow_size_tls