[PATCH] Fix a mergefunc crash caused by bitcasting intrinsics

Björn Steinbrink bsteinbr at gmail.com
Wed Apr 23 01:15:43 PDT 2014


Fix a mergefunc crash caused by bitcasting intrinsics

In general, if we're dealing with two distinct function constants, bitcasting
one of them will not result in the other, so we can skip the cast and just
return false.

CHANGES SINCE LAST UPDATE
  http://reviews.llvm.org/D3437?vs=8715&id=8760

BRANCH
  mergefunc

http://reviews.llvm.org/D3437

Files:
  lib/Transforms/IPO/MergeFunctions.cpp
  test/Transforms/MergeFunc/intrinsics.ll

Index: lib/Transforms/IPO/MergeFunctions.cpp
===================================================================
--- lib/Transforms/IPO/MergeFunctions.cpp
+++ lib/Transforms/IPO/MergeFunctions.cpp
@@ -465,6 +465,8 @@
     if (C1->isNullValue() && C2->isNullValue() &&
         isEquivalentType(C1->getType(), C2->getType()))
       return true;
+    if (isa<Function>(V1) || isa<Function>(V2))
+      return false;
     // Try bitcasting C2 to C1's type. If the bitcast is legal and returns C1
     // then they must have equal bit patterns.
     return C1->getType()->canLosslesslyBitCastTo(C2->getType()) &&
Index: test/Transforms/MergeFunc/intrinsics.ll
===================================================================
--- /dev/null
+++ test/Transforms/MergeFunc/intrinsics.ll
@@ -0,0 +1,35 @@
+; RUN: opt -S -mergefunc < %s | FileCheck %s
+; This used to crash because mergefunc created a bitcast of an intrinsic.
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-unknown-linux-gnu"
+
+declare i64 @llvm.bswap.i64(i64) unnamed_addr nounwind readnone
+declare i8* @breaker(i8*) unnamed_addr
+
+; @bswap_caller and @collider have the same hash in mergefunc and get fed to
+; enumerate, which used to create a bitcast of the bswap intrinsic that
+; survived on the intrinsics uselist and made the verify pass complain.
+; The repeated calls are just to make the functions large enough to be merged
+; and test that they aren't merged, regardless of the above bug.
+define void @bswap_caller(i64) unnamed_addr {
+; CHECK-LABEL: @bswap_caller(
+entry-block:
+  call i64 @llvm.bswap.i64(i64 %0)
+  call i64 @llvm.bswap.i64(i64 %0)
+  call i64 @llvm.bswap.i64(i64 %0)
+  call i64 @llvm.bswap.i64(i64 %0)
+  ret void
+}
+
+define internal void @collider(i8*) unnamed_addr {
+; CHECK-LABEL: @collider(
+entry-block:
+  call i8* @breaker(i8* %0)
+  call i8* @breaker(i8* %0)
+  call i8* @breaker(i8* %0)
+  call i8* @breaker(i8* %0)
+  ret void
+}
+
+; CHECK-NOT:  "functions merged"

REPLY HANDLER ACTIONS
  Reply to comment, or !reject, !abandon, !reclaim, !resign, !rethink, !unsubscribe.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D3437.8760.patch
Type: text/x-patch
Size: 2127 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140423/3cdce865/attachment.bin>


More information about the llvm-commits mailing list