@@ -162,6 +162,23 @@ void ABIArgInfo::dump() const {
162
162
OS << " )\n " ;
163
163
}
164
164
165
+ // Dynamically round a pointer up to a multiple of the given alignment.
166
+ static llvm::Value *emitRoundPointerUpToAlignment (CodeGenFunction &CGF,
167
+ llvm::Value *Ptr ,
168
+ CharUnits Align) {
169
+ llvm::Value *PtrAsInt = Ptr ;
170
+ // OverflowArgArea = (OverflowArgArea + Align - 1) & -Align;
171
+ PtrAsInt = CGF.Builder .CreatePtrToInt (PtrAsInt, CGF.IntPtrTy );
172
+ PtrAsInt = CGF.Builder .CreateAdd (PtrAsInt,
173
+ llvm::ConstantInt::get (CGF.IntPtrTy , Align.getQuantity () - 1 ));
174
+ PtrAsInt = CGF.Builder .CreateAnd (PtrAsInt,
175
+ llvm::ConstantInt::get (CGF.IntPtrTy , -Align.getQuantity ()));
176
+ PtrAsInt = CGF.Builder .CreateIntToPtr (PtrAsInt,
177
+ Ptr ->getType (),
178
+ Ptr ->getName () + " .aligned" );
179
+ return PtrAsInt;
180
+ }
181
+
165
182
// / Emit va_arg for a platform using the common void* representation,
166
183
// / where arguments are simply emitted in an array of slots on the stack.
167
184
// /
@@ -193,17 +210,10 @@ static Address emitVoidPtrDirectVAArg(CodeGenFunction &CGF,
193
210
// If the CC aligns values higher than the slot size, do so if needed.
194
211
Address Addr = Address::invalid ();
195
212
if (AllowHigherAlign && DirectAlign > SlotSize) {
196
- llvm::Value *PtrAsInt = Ptr ;
197
- PtrAsInt = CGF.Builder .CreatePtrToInt (PtrAsInt, CGF.IntPtrTy );
198
- PtrAsInt = CGF.Builder .CreateAdd (PtrAsInt,
199
- llvm::ConstantInt::get (CGF.IntPtrTy , DirectAlign.getQuantity () - 1 ));
200
- PtrAsInt = CGF.Builder .CreateAnd (PtrAsInt,
201
- llvm::ConstantInt::get (CGF.IntPtrTy , -DirectAlign.getQuantity ()));
202
- Addr = Address (CGF.Builder .CreateIntToPtr (PtrAsInt, Ptr ->getType (),
203
- " argp.cur.aligned" ),
204
- DirectAlign);
213
+ Addr = Address (emitRoundPointerUpToAlignment (CGF, Ptr , DirectAlign),
214
+ DirectAlign);
205
215
} else {
206
- Addr = Address (Ptr , SlotSize);
216
+ Addr = Address (Ptr , SlotSize);
207
217
}
208
218
209
219
// Advance the pointer past the argument, then store that back.
@@ -3072,19 +3082,10 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
3072
3082
// byte boundary if alignment needed by type exceeds 8 byte boundary.
3073
3083
// It isn't stated explicitly in the standard, but in practice we use
3074
3084
// alignment greater than 16 where necessary.
3075
- uint64_t Align = CGF.getContext ().getTypeAlignInChars (Ty).getQuantity ();
3076
- if (Align > 8 ) {
3077
- // overflow_arg_area = (overflow_arg_area + align - 1) & -align;
3078
- llvm::Value *Offset =
3079
- llvm::ConstantInt::get (CGF.Int64Ty , Align - 1 );
3080
- overflow_arg_area = CGF.Builder .CreateGEP (overflow_arg_area, Offset);
3081
- llvm::Value *AsInt = CGF.Builder .CreatePtrToInt (overflow_arg_area,
3082
- CGF.Int64Ty );
3083
- llvm::Value *Mask = llvm::ConstantInt::get (CGF.Int64Ty , -(uint64_t )Align);
3084
- overflow_arg_area =
3085
- CGF.Builder .CreateIntToPtr (CGF.Builder .CreateAnd (AsInt, Mask),
3086
- overflow_arg_area->getType (),
3087
- " overflow_arg_area.align" );
3085
+ CharUnits Align = CGF.getContext ().getTypeAlignInChars (Ty);
3086
+ if (Align > CharUnits::fromQuantity (8 )) {
3087
+ overflow_arg_area = emitRoundPointerUpToAlignment (CGF, overflow_arg_area,
3088
+ Align);
3088
3089
}
3089
3090
3090
3091
// AMD64-ABI 3.5.7p5: Step 8. Fetch type from l->overflow_arg_area.
@@ -3106,7 +3107,7 @@ static Address EmitX86_64VAArgFromMemory(CodeGenFunction &CGF,
3106
3107
CGF.Builder .CreateStore (overflow_arg_area, overflow_arg_area_p);
3107
3108
3108
3109
// AMD64-ABI 3.5.7p5: Step 11. Return the fetched type.
3109
- return Address (Res, CharUnits::fromQuantity ( Align) );
3110
+ return Address (Res, Align);
3110
3111
}
3111
3112
3112
3113
Address X86_64ABIInfo::EmitVAArg (CodeGenFunction &CGF, Address VAListAddr,
@@ -3541,11 +3542,16 @@ Address PPC32_SVR4_ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAList,
3541
3542
3542
3543
Address OverflowAreaAddr =
3543
3544
Builder.CreateStructGEP (VAList, 3 , CharUnits::fromQuantity (4 ));
3544
- Address OverflowArea (Builder.CreateLoad (OverflowAreaAddr),
3545
+ Address OverflowArea (Builder.CreateLoad (OverflowAreaAddr, " argp.cur " ),
3545
3546
OverflowAreaAlign);
3546
-
3547
- // The current address is the address of the varargs element.
3548
- // FIXME: do we not need to round up to alignment?
3547
+ // Round up address of argument to alignment
3548
+ CharUnits Align = CGF.getContext ().getTypeAlignInChars (Ty);
3549
+ if (Align > OverflowAreaAlign) {
3550
+ llvm::Value *Ptr = OverflowArea.getPointer ();
3551
+ OverflowArea = Address (emitRoundPointerUpToAlignment (CGF, Ptr , Align),
3552
+ Align);
3553
+ }
3554
+
3549
3555
MemAddr = Builder.CreateElementBitCast (OverflowArea, DirectTy);
3550
3556
3551
3557
// Increase the overflow area.
0 commit comments