[PATCH] D119967: [InstCombineCalls] Optimize call of bitcast even w/ parameter attributes

Johannes Doerfert via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed Feb 16 12:39:02 PST 2022


jdoerfert created this revision.
jdoerfert added reviewers: aeubanks, lebedev.ri, nikic, reames, spatel.
Herald added subscribers: bollu, hiraditya.
jdoerfert requested review of this revision.
Herald added a project: LLVM.

Before we gave up if a call through bitcast had parameter attributes.
Interestingly, we allowed attributes for the return value already. We
now handle both the same way, namely, we drop the ones that are
incompatible with the new type and keep the rest. This cannot cause
"more UB" than initially present.


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D119967

Files:
  llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
  llvm/test/Transforms/InstCombine/call-cast-attrs.ll


Index: llvm/test/Transforms/InstCombine/call-cast-attrs.ll
===================================================================
--- llvm/test/Transforms/InstCombine/call-cast-attrs.ll
+++ llvm/test/Transforms/InstCombine/call-cast-attrs.ll
@@ -1,4 +1,5 @@
-; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+; RUN: opt < %s -passes=instcombine -data-layout="p:32:32" -S | FileCheck %s --check-prefixes=CHECK,CHECK32
+; RUN: opt < %s -passes=instcombine -data-layout="p:64:64" -S | FileCheck %s --check-prefixes=CHECK,CHECK64
 
 define signext i32 @b(i32* inreg %x)   {
   ret i32 0
@@ -20,10 +21,17 @@
   call void bitcast (void (...)* @c to void (i32*)*)(i32* %y)
   call void bitcast (void (...)* @c to void (i32*)*)(i32* sret(i32) %y)
   call void bitcast (void (i32, ...)* @d to void (i32, i32*)*)(i32 0, i32* sret(i32) %y)
+  call void bitcast (void (i32, ...)* @d to void (i32, i32*)*)(i32 0, i32* nocapture %y)
+  call void bitcast (void (i32, ...)* @d to void (i32*)*)(i32* nocapture noundef %y)
   ret void
 }
 ; CHECK-LABEL: define void @g(i32* %y)
-; CHECK: call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)(i32 zeroext 0)
-; CHECK: call void (...) @c(i32* %y)
-; CHECK: call void bitcast (void (...)* @c to void (i32*)*)(i32* sret(i32) %y)
-; CHECK: call void bitcast (void (i32, ...)* @d to void (i32, i32*)*)(i32 0, i32* sret(i32) %y)
+; CHECK32:  %1 = call i32 @b(i32* null)
+; CHECK64:  call i32 bitcast (i32 (i32*)* @b to i32 (i32)*)(i32 zeroext 0)
+; CHECK:    call void (...) @c(i32* %y)
+; CHECK:    call void bitcast (void (...)* @c to void (i32*)*)(i32* sret(i32) %y)
+; CHECK:    call void bitcast (void (i32, ...)* @d to void (i32, i32*)*)(i32 0, i32* sret(i32) %y)
+; CHECK:    call void (i32, ...) @d(i32 0, i32* nocapture %y)
+; CHECK32:  %2 = ptrtoint i32* %y to i32
+; CHECK32:  call void (i32, ...) @d(i32 noundef %2)
+; CHECK64:  call void bitcast (void (i32, ...)* @d to void (i32*)*)(i32* nocapture noundef %y)
Index: llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
===================================================================
--- llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
+++ llvm/lib/Transforms/InstCombine/InstCombineCalls.cpp
@@ -3064,12 +3064,9 @@
     if (!CastInst::isBitOrNoopPointerCastable(ActTy, ParamTy, DL))
       return false;   // Cannot transform this parameter value.
 
-    if (AttrBuilder(FT->getContext(), CallerPAL.getParamAttrs(i))
-            .overlaps(AttributeFuncs::typeIncompatible(ParamTy)))
-      return false;   // Attribute not compatible with transformed value.
-
-    if (Call.isInAllocaArgument(i))
-      return false;   // Cannot transform to and from inalloca.
+    if (Call.isInAllocaArgument(i) ||
+        CallerPAL.hasParamAttr(i, Attribute::Preallocated))
+      return false; // Cannot transform to and from inalloca/preallocated.
 
     if (CallerPAL.hasParamAttr(i, Attribute::SwiftError))
       return false;
@@ -3142,13 +3139,19 @@
       NewArg = Builder.CreateBitOrPointerCast(*AI, ParamTy);
     Args.push_back(NewArg);
 
-    // Add any parameter attributes.
+    // Add any parameter attributes except the ones incompatible with the new
+    // type.
     if (CallerPAL.hasParamAttr(i, Attribute::ByVal)) {
-      AttrBuilder AB(FT->getContext(), CallerPAL.getParamAttrs(i));
+      AttrBuilder AB(
+          FT->getContext(),
+          CallerPAL.getParamAttrs(i).removeAttributes(
+              FT->getContext(), AttributeFuncs::typeIncompatible(ParamTy)));
       AB.addByValAttr(NewArg->getType()->getPointerElementType());
       ArgAttrs.push_back(AttributeSet::get(Ctx, AB));
-    } else
-      ArgAttrs.push_back(CallerPAL.getParamAttrs(i));
+    } else {
+      ArgAttrs.push_back(CallerPAL.getParamAttrs(i).removeAttributes(
+          FT->getContext(), AttributeFuncs::typeIncompatible(ParamTy)));
+    }
   }
 
   // If the function takes more arguments than the call was taking, add them


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D119967.409371.patch
Type: text/x-patch
Size: 3916 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20220216/edd81b33/attachment.bin>


More information about the llvm-commits mailing list