[llvm] 8e0ff44 - [InstCombine] Make varargs cast transform compatible with opaque ptrs

Nikita Popov via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 24 12:57:15 PDT 2021


Author: Nikita Popov
Date: 2021-06-24T21:57:05+02:00
New Revision: 8e0ff44bf896733f04c5cc9e68aee2b777860ddd

URL: https://github.com/llvm/llvm-project/commit/8e0ff44bf896733f04c5cc9e68aee2b777860ddd
DIFF: https://github.com/llvm/llvm-project/commit/8e0ff44bf896733f04c5cc9e68aee2b777860ddd.diff

LOG: [InstCombine] Make varargs cast transform compatible with opaque ptrs

The whole transform can be dropped once we have fully transitioned
to opaque pointers (as it's purpose is to remove no-op pointer
casts). For now, make sure that it handles opaque pointers correctly.

Added: 
    

Modified: 
    llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
    llvm/test/Transforms/InstCombine/opaque-ptr.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
index ece98ffe39f46..256c79dbdf1dd 100644
--- a/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -2031,20 +2031,27 @@ static bool isSafeToEliminateVarargsCast(const CallBase &Call,
       isa<GCResultInst>(Call))
     return false;
 
+  // Opaque pointers are compatible with any byval types.
+  PointerType *SrcTy = cast<PointerType>(CI->getOperand(0)->getType());
+  if (SrcTy->isOpaque())
+    return true;
+
   // The size of ByVal or InAlloca arguments is derived from the type, so we
   // can't change to a type with a 
diff erent size.  If the size were
   // passed explicitly we could avoid this check.
   if (!Call.isPassPointeeByValueArgument(ix))
     return true;
 
-  Type* SrcTy =
-            cast<PointerType>(CI->getOperand(0)->getType())->getElementType();
-  Type *DstTy = Call.isByValArgument(ix)
-                    ? Call.getParamByValType(ix)
-                    : cast<PointerType>(CI->getType())->getElementType();
-  if (!SrcTy->isSized() || !DstTy->isSized())
+  // The transform currently only handles type replacement for byval, not other
+  // type-carrying attributes.
+  if (!Call.isByValArgument(ix))
+    return false;
+
+  Type *SrcElemTy = SrcTy->getElementType();
+  Type *DstElemTy = Call.getParamByValType(ix);
+  if (!SrcElemTy->isSized() || !DstElemTy->isSized())
     return false;
-  if (DL.getTypeAllocSize(SrcTy) != DL.getTypeAllocSize(DstTy))
+  if (DL.getTypeAllocSize(SrcElemTy) != DL.getTypeAllocSize(DstElemTy))
     return false;
   return true;
 }
@@ -2310,6 +2317,7 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
   if (IntrinsicInst *II = findInitTrampoline(Callee))
     return transformCallThroughTrampoline(Call, *II);
 
+  // TODO: Drop this transform once opaque pointer transition is done.
   FunctionType *FTy = Call.getFunctionType();
   if (FTy->isVarArg()) {
     int ix = FTy->getNumParams();
@@ -2321,13 +2329,14 @@ Instruction *InstCombinerImpl::visitCallBase(CallBase &Call) {
       if (CI && isSafeToEliminateVarargsCast(Call, DL, CI, ix)) {
         replaceUse(*I, CI->getOperand(0));
 
-        // Update the byval type to match the argument type.
-        if (Call.isByValArgument(ix)) {
+        // Update the byval type to match the pointer type.
+        // Not necessary for opaque pointers.
+        PointerType *NewTy = cast<PointerType>(CI->getOperand(0)->getType());
+        if (!NewTy->isOpaque() && Call.isByValArgument(ix)) {
           Call.removeParamAttr(ix, Attribute::ByVal);
           Call.addParamAttr(
               ix, Attribute::getWithByValType(
-                      Call.getContext(),
-                      CI->getOperand(0)->getType()->getPointerElementType()));
+                      Call.getContext(), NewTy->getElementType()));
         }
         Changed = true;
       }

diff  --git a/llvm/test/Transforms/InstCombine/opaque-ptr.ll b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
index 6a83587a3fca8..a996c619525a2 100644
--- a/llvm/test/Transforms/InstCombine/opaque-ptr.ll
+++ b/llvm/test/Transforms/InstCombine/opaque-ptr.ll
@@ -124,3 +124,45 @@ define void @call(ptr %a) {
   call void %a()
   ret void
 }
+
+declare void @varargs(...)
+define void @varargs_cast_typed_to_opaque_same_type(i32* %a) {
+; CHECK-LABEL: @varargs_cast_typed_to_opaque_same_type(
+; CHECK-NEXT:    call void (...) @varargs(i32* byval(i32) [[A:%.*]])
+; CHECK-NEXT:    ret void
+;
+  %b = bitcast i32* %a to ptr
+  call void (...) @varargs(ptr byval(i32) %b)
+  ret void
+}
+
+define void @varargs_cast_typed_to_opaque_
diff erent_type(i32* %a) {
+; CHECK-LABEL: @varargs_cast_typed_to_opaque_
diff erent_type(
+; CHECK-NEXT:    call void (...) @varargs(i32* byval(i32) [[A:%.*]])
+; CHECK-NEXT:    ret void
+;
+  %b = bitcast i32* %a to ptr
+  call void (...) @varargs(ptr byval(float) %b)
+  ret void
+}
+
+define void @varargs_cast_typed_to_opaque_
diff erent_size(i32* %a) {
+; CHECK-LABEL: @varargs_cast_typed_to_opaque_
diff erent_size(
+; CHECK-NEXT:    [[B:%.*]] = bitcast i32* [[A:%.*]] to ptr
+; CHECK-NEXT:    call void (...) @varargs(ptr byval(i64) [[B]])
+; CHECK-NEXT:    ret void
+;
+  %b = bitcast i32* %a to ptr
+  call void (...) @varargs(ptr byval(i64) %b)
+  ret void
+}
+
+define void @varargs_cast_opaque_to_typed(ptr %a) {
+; CHECK-LABEL: @varargs_cast_opaque_to_typed(
+; CHECK-NEXT:    call void (...) @varargs(ptr byval(i8) [[A:%.*]])
+; CHECK-NEXT:    ret void
+;
+  %b = bitcast ptr %a to i8*
+  call void (...) @varargs(i8* byval(i8) %b)
+  ret void
+}


        


More information about the llvm-commits mailing list