[clang] 2276733 - [X86] Always check the size of SourceTy before getting the next type

via cfe-commits cfe-commits at lists.llvm.org
Mon Sep 20 08:34:37 PDT 2021


Author: Wang, Pengfei
Date: 2021-09-20T23:34:19+08:00
New Revision: 227673398c2d93d9db02fe5fdb1af10a74251995

URL: https://github.com/llvm/llvm-project/commit/227673398c2d93d9db02fe5fdb1af10a74251995
DIFF: https://github.com/llvm/llvm-project/commit/227673398c2d93d9db02fe5fdb1af10a74251995.diff

LOG: [X86] Always check the size of SourceTy before getting the next type

D109607 results in a regression in llvm-test-suite.
The reason is we didn't check the size of SourceTy, so that we will
return wrong SSE type when SourceTy is overlapped.

Reviewed By: Meinersbur

Differential Revision: https://reviews.llvm.org/D110037

Added: 
    

Modified: 
    clang/lib/CodeGen/TargetInfo.cpp
    clang/test/CodeGen/X86/va-arg-sse.c

Removed: 
    


################################################################################
diff  --git a/clang/lib/CodeGen/TargetInfo.cpp b/clang/lib/CodeGen/TargetInfo.cpp
index 58d43bd36565..bebadc44725c 100644
--- a/clang/lib/CodeGen/TargetInfo.cpp
+++ b/clang/lib/CodeGen/TargetInfo.cpp
@@ -3438,17 +3438,21 @@ llvm::Type *X86_64ABIInfo::
 GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
                    QualType SourceTy, unsigned SourceOffset) const {
   const llvm::DataLayout &TD = getDataLayout();
+  unsigned SourceSize =
+      (unsigned)getContext().getTypeSize(SourceTy) / 8 - SourceOffset;
   llvm::Type *T0 = getFPTypeAtOffset(IRType, IROffset, TD);
   if (!T0 || T0->isDoubleTy())
     return llvm::Type::getDoubleTy(getVMContext());
 
   // Get the adjacent FP type.
-  llvm::Type *T1 =
-      getFPTypeAtOffset(IRType, IROffset + TD.getTypeAllocSize(T0), TD);
+  llvm::Type *T1 = nullptr;
+  unsigned T0Size = TD.getTypeAllocSize(T0);
+  if (SourceSize > T0Size)
+      T1 = getFPTypeAtOffset(IRType, IROffset + T0Size, TD);
   if (T1 == nullptr) {
     // Check if IRType is a half + float. float type will be in IROffset+4 due
     // to its alignment.
-    if (T0->isHalfTy())
+    if (T0->isHalfTy() && SourceSize > 4)
       T1 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
     // If we can't get a second FP type, return a simple half or float.
     // avx512fp16-abi.c:pr51813_2 shows it works to return float for
@@ -3461,7 +3465,9 @@ GetSSETypeAtOffset(llvm::Type *IRType, unsigned IROffset,
     return llvm::FixedVectorType::get(T0, 2);
 
   if (T0->isHalfTy() && T1->isHalfTy()) {
-    llvm::Type *T2 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
+    llvm::Type *T2 = nullptr;
+    if (SourceSize > 4)
+      T2 = getFPTypeAtOffset(IRType, IROffset + 4, TD);
     if (T2 == nullptr)
       return llvm::FixedVectorType::get(T0, 2);
     return llvm::FixedVectorType::get(T0, 4);

diff  --git a/clang/test/CodeGen/X86/va-arg-sse.c b/clang/test/CodeGen/X86/va-arg-sse.c
index 3f146fc08337..4380d0580e05 100644
--- a/clang/test/CodeGen/X86/va-arg-sse.c
+++ b/clang/test/CodeGen/X86/va-arg-sse.c
@@ -34,16 +34,16 @@ struct S a[5];
 // CHECK-NEXT:    [[REG_SAVE_AREA:%.*]] = load i8*, i8** [[TMP0]], align 16
 // CHECK-NEXT:    [[TMP1:%.*]] = getelementptr i8, i8* [[REG_SAVE_AREA]], i32 [[FP_OFFSET]]
 // CHECK-NEXT:    [[TMP2:%.*]] = getelementptr inbounds i8, i8* [[TMP1]], i64 16
-// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %struct.S* [[TMP]] to { <2 x float>, <2 x float> }*
+// CHECK-NEXT:    [[TMP3:%.*]] = bitcast %struct.S* [[TMP]] to { <2 x float>, float }*
 // CHECK-NEXT:    [[TMP4:%.*]] = bitcast i8* [[TMP1]] to <2 x float>*
 // CHECK-NEXT:    [[TMP5:%.*]] = load <2 x float>, <2 x float>* [[TMP4]], align 16
-// CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* [[TMP3]], i32 0, i32 0
+// CHECK-NEXT:    [[TMP6:%.*]] = getelementptr inbounds { <2 x float>, float }, { <2 x float>, float }* [[TMP3]], i32 0, i32 0
 // CHECK-NEXT:    store <2 x float> [[TMP5]], <2 x float>* [[TMP6]], align 4
-// CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP2]] to <2 x float>*
-// CHECK-NEXT:    [[TMP8:%.*]] = load <2 x float>, <2 x float>* [[TMP7]], align 16
-// CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds { <2 x float>, <2 x float> }, { <2 x float>, <2 x float> }* [[TMP3]], i32 0, i32 1
-// CHECK-NEXT:    store <2 x float> [[TMP8]], <2 x float>* [[TMP9]], align 4
-// CHECK-NEXT:    [[TMP10:%.*]] = bitcast { <2 x float>, <2 x float> }* [[TMP3]] to %struct.S*
+// CHECK-NEXT:    [[TMP7:%.*]] = bitcast i8* [[TMP2]] to float*
+// CHECK-NEXT:    [[TMP8:%.*]] = load float, float* [[TMP7]], align 16
+// CHECK-NEXT:    [[TMP9:%.*]] = getelementptr inbounds { <2 x float>, float }, { <2 x float>, float }* [[TMP3]], i32 0, i32 1
+// CHECK-NEXT:    store float [[TMP8]], float* [[TMP9]], align 4
+// CHECK-NEXT:    [[TMP10:%.*]] = bitcast { <2 x float>, float }* [[TMP3]] to %struct.S*
 // CHECK-NEXT:    [[TMP11:%.*]] = add i32 [[FP_OFFSET]], 32
 // CHECK-NEXT:    store i32 [[TMP11]], i32* [[FP_OFFSET_P]], align 4
 // CHECK-NEXT:    br label [[VAARG_END:%.*]]


        


More information about the cfe-commits mailing list