[PATCH] Fix a mergefunc crash caused by bitcasting intrinsics

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


Fixed the test to include -stats

Sorry, didn't notice that as there's no way to actually make that CHECK-NOT
assetion fail with the given test case.

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

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 -stats < %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.8761.patch
Type: text/x-patch
Size: 2134 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20140423/c49f62d3/attachment.bin>


More information about the llvm-commits mailing list