Situations can arise when you have a function called that returns a 'void', but
authorBill Wendling <isanbard@gmail.com>
Wed, 14 May 2008 22:45:20 +0000 (22:45 +0000)
committerBill Wendling <isanbard@gmail.com>
Wed, 14 May 2008 22:45:20 +0000 (22:45 +0000)
is bitcast to return a floating point value. The result of the instruction may
not be used by the program afterwards, and LLVM will happily remove all
instructions except the call. But, on some platforms, if a value is returned as
a floating point, it may need to be removed from the stack (like x87). Thus, we
can't get rid of the bitcast even if there isn't a use of the value.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@51134 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Transforms/Scalar/InstructionCombining.cpp
test/Transforms/InstCombine/2003-11-13-ConstExprCastCall.ll
test/Transforms/InstCombine/fp-ret-bitcast.ll [new file with mode: 0644]

index 06620557daa6018dbca208a76577590ae8de9405..bb4b7016dc4f80bf2ea9322a570d92c9a1158146 100644 (file)
@@ -8940,7 +8940,7 @@ bool InstCombiner::transformConstExprCastCall(CallSite CS) {
 
   // Check to see if we are changing the return type...
   if (OldRetTy != FT->getReturnType()) {
-    if (Callee->isDeclaration() && !Caller->use_empty() && 
+    if (Callee->isDeclaration() &&
         // Conversion is ok if changing from pointer to int of same size.
         !(isa<PointerType>(FT->getReturnType()) &&
           TD->getIntPtrType() == OldRetTy))
@@ -11516,7 +11516,7 @@ bool InstCombiner::runOnFunction(Function &F) {
 
   // Iterate while there is work to do.
   unsigned Iteration = 0;
-  while (DoOneIteration(F, Iteration++)) 
+  while (DoOneIteration(F, Iteration++))
     EverMadeChange = true;
   return EverMadeChange;
 }
index 23fe07d2b307b009d3a824dde2693f3dc73eced0..b6930b5a65fde01fe657d105526866d3fc528326 100644 (file)
@@ -3,7 +3,6 @@
 declare void @free(i8*)
 
 define void @test(i32* %X) {
-        call i32 (...)* bitcast (void (i8*)* @free to i32 (...)*)( i32* %X )            ; <i32>:1 [#uses=0]
+        call void (...)* bitcast (void (i8*)* @free to void (...)*)( i32* %X )          ; <i32>:1 [#uses=0]
         ret void
 }
-
diff --git a/test/Transforms/InstCombine/fp-ret-bitcast.ll b/test/Transforms/InstCombine/fp-ret-bitcast.ll
new file mode 100644 (file)
index 0000000..00c1ea0
--- /dev/null
@@ -0,0 +1,27 @@
+; RUN: llvm-as < %s | opt -instcombine | llvm-dis | \
+; RUN:    grep {call float bitcast} | count 1
+       %struct.NSObject = type { %struct.objc_class* }
+       %struct.NSArray = type { %struct.NSObject }
+       %struct.objc_class = type opaque
+       %struct.objc_selector = type opaque
+
+@"\01L_OBJC_METH_VAR_NAME_112" = internal global [15 x i8] c"whiteComponent\00", section "__TEXT,__cstring,cstring_literals"
+@"\01L_OBJC_SELECTOR_REFERENCES_81" = internal global %struct.objc_selector* bitcast ([15 x i8]* @"\01L_OBJC_METH_VAR_NAME_112" to %struct.objc_selector*), section "__OBJC,__message_refs,literal_pointers,no_dead_strip"
+
+define void @bork() nounwind  {
+entry:
+       %color = alloca %struct.NSArray*
+       %color.466 = alloca %struct.NSObject*
+       %tmp103 = load %struct.NSArray** %color, align 4
+       %tmp103104 = getelementptr %struct.NSArray* %tmp103, i32 0, i32 0
+       store %struct.NSObject* %tmp103104, %struct.NSObject** %color.466, align 4
+       %tmp105 = load %struct.objc_selector** @"\01L_OBJC_SELECTOR_REFERENCES_81", align 4
+       %tmp106 = load %struct.NSObject** %color.466, align 4
+       %tmp107 = call float bitcast (void (%struct.NSObject*, ...)* @objc_msgSend_fpret to float (%struct.NSObject*, %struct.objc_selector*)*)( %struct.NSObject* %tmp106, %struct.objc_selector* %tmp105 ) nounwind
+       br label %exit
+
+exit:
+       ret void
+}
+
+declare void @objc_msgSend_fpret(%struct.NSObject*, ...)