[llvm] [MSan] Separated PPC32 va_arg helper from PPC64 (PR #131827)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Apr 9 07:00:18 PDT 2025
================
@@ -6601,45 +6576,51 @@ struct VarArgPowerPC32Helper : public VarArgHelperBase {
kShadowTLSAlignment, ArgSize);
}
}
- VAArgOffset += alignTo(ArgSize, Align(8));
+ VAArgOffset += alignTo(ArgSize, Align(IntptrSize));
} else {
Value *Base;
- uint64_t ArgSize = DL.getTypeAllocSize(A->getType());
- Align ArgAlign = Align(8);
- if (A->getType()->isArrayTy()) {
- // Arrays are aligned to element size, except for long double
- // arrays, which are aligned to 8 bytes.
- Type *ElementTy = A->getType()->getArrayElementType();
- if (!ElementTy->isPPC_FP128Ty())
- ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
- } else if (A->getType()->isVectorTy()) {
- // Vectors are naturally aligned.
- ArgAlign = Align(ArgSize);
- }
- if (ArgAlign < 8)
- ArgAlign = Align(8);
- VAArgOffset = alignTo(VAArgOffset, ArgAlign);
- if (DL.isBigEndian()) {
- // Adjusting the shadow for argument with size < 8 to match the
- // placement of bits in big endian system
- if (ArgSize < 8)
- VAArgOffset += (8 - ArgSize);
- }
- if (!IsFixed) {
- Base =
- getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase, ArgSize);
- if (Base)
- IRB.CreateAlignedStore(MSV.getShadow(A), Base, kShadowTLSAlignment);
+ Type *ArgTy = A->getType();
+
+ // On PPC 32 floating point variable arguments are stored in separate
+ // area: fp_save_area = reg_save_area + 4*8. We do not copy shaodow for
+ // them as they will be found when checking call arguments.
+ if (!ArgTy->isFloatingPointTy()) {
+ uint64_t ArgSize = DL.getTypeAllocSize(ArgTy);
+ Align ArgAlign = Align(IntptrSize);
+ if (ArgTy->isArrayTy()) {
+ // Arrays are aligned to element size, except for long double
+ // arrays, which are aligned to 8 bytes.
+ Type *ElementTy = ArgTy->getArrayElementType();
+ if (!ElementTy->isPPC_FP128Ty())
+ ArgAlign = Align(DL.getTypeAllocSize(ElementTy));
+ } else if (ArgTy->isVectorTy()) {
+ // Vectors are naturally aligned.
+ ArgAlign = Align(ArgSize);
+ }
+ if (ArgAlign < IntptrSize)
+ ArgAlign = Align(IntptrSize);
+ VAArgOffset = alignTo(VAArgOffset, ArgAlign);
+ if (DL.isBigEndian()) {
+ // Adjusting the shadow for argument with size < IntptrSize to match
+ // the placement of bits in big endian system
+ if (ArgSize < IntptrSize)
+ VAArgOffset += (IntptrSize - ArgSize);
+ }
+ if (!IsFixed) {
+ Base = getShadowPtrForVAArgument(IRB, VAArgOffset - VAArgBase,
+ ArgSize);
+ if (Base)
+ IRB.CreateAlignedStore(MSV.getShadow(A), Base,
+ kShadowTLSAlignment);
+ }
+ VAArgOffset += ArgSize;
+ VAArgOffset = alignTo(VAArgOffset, Align(IntptrSize));
}
- VAArgOffset += ArgSize;
- VAArgOffset = alignTo(VAArgOffset, Align(8));
}
- if (IsFixed)
- VAArgBase = VAArgOffset;
}
Constant *TotalVAArgSize =
- ConstantInt::get(MS.IntptrTy, VAArgOffset - VAArgBase);
+ ConstantInt::get(IRB.getInt32Ty(), VAArgOffset - VAArgBase);
----------------
k-kashapov wrote:
I've tried to change the type to `MS.IntptrTy` and added this line:
```cpp
llvm::outs() << "IntPtrTy = " << *MS.IntptrTy << "\n";
```
Here's the output from opt:
```bash
$ bin/opt < ../llvm/test/Instrumentation/MemorySanitizer/PowerPC32/vararg-ppcle.ll -S -passes=msan -msan-origin-base=0x40000000 -msan-and-mask=0x80000000 2>&1
IntPtrTy = i64
; ModuleID = '<stdin>'
source_filename = "<stdin>"
target datalayout = "e-m:e-i32:32-n32"
target triple = "powerpcle--linux"
...
define i32 @foo(i32 %guard, ...) {
%1 = load i64, ptr @__msan_va_arg_overflow_size_tls, align 4
%2 = alloca i8, i64 %1, align 8
call void @llvm.memset.p0.i64(ptr align 8 %2, i8 0, i64 %1, i1 false)
%3 = call i64 @llvm.umin.i64(i64 %1, i64 800)
call void @llvm.memcpy.p0.p0.i64(ptr align 8 %2, ptr align 8 @__msan_va_arg_tls, i64 %3, i1 false)
...
```
As you can see, opt uses i64 as `MS.IntptrTy`. However when compiling with clang, it suddenly becomes i32:
```bash
$ clang test.c -target powerpc-gnu-linux-eabi -c -fsanitize=memory -mllvm -msan-shadow-base=0x40000000
IntPtrTy = i32
```
I don't know what may cause this, so i've decided to keep `getInt32Ty()` for now.
https://github.com/llvm/llvm-project/pull/131827
More information about the llvm-commits
mailing list