Skip to content

Commit

Permalink
instcombine: Don't replace all uses for instructions with no uses
Browse files Browse the repository at this point in the history
My commit to migrate the printf simplifiers from the simplify-libcalls
in r168604 introduced a regression reported by Duncan [1].  The problem
is that in some cases the library call simplifier can return a new value
that has no uses and the new value's type is different than the old value's
type (which is fine because there are no uses).  The specific case that
triggered the bug looked something like:

   declare void @printf(i8*, ...)
   ...
   call void (i8*, ...)* @printf(i8* %fmt)

Which we want to optimized into:

   call i32 @putchar(i32 104)

However, the code was attempting to replace all uses of the printf with
the putchar and the types differ, hence a crash.  This is fixed by *just*
deleting the original instruction when there are no uses.  The old
simplify-libcalls pass is already doing something similar.

[1] http://lists.cs.uiuc.edu/pipermail/llvmdev/2012-November/056338.html

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@168716 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
meadori committed Nov 27, 2012
1 parent 9e3c388 commit a241b58
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 1 deletion.
2 changes: 1 addition & 1 deletion lib/Transforms/InstCombine/InstCombineCalls.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -786,7 +786,7 @@ Instruction *InstCombiner::tryOptimizeCall(CallInst *CI, const DataLayout *TD) {
if (CI->getCalledFunction() == 0) return 0;

if (Value *With = Simplifier->optimizeCall(CI))
return ReplaceInstUsesWith(*CI, With);
return CI->use_empty() ? CI : ReplaceInstUsesWith(*CI, With);

return 0;
}
Expand Down
41 changes: 41 additions & 0 deletions test/Transforms/InstCombine/printf-2.ll
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
; Test that the printf library call simplifier works correctly.
;
; RUN: opt < %s -instcombine -S | FileCheck %s

target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"

@hello_world = constant [13 x i8] c"hello world\0A\00"
@h = constant [2 x i8] c"h\00"
@percent_s = constant [4 x i8] c"%s\0A\00"

declare void @printf(i8*, ...)

; Check simplification of printf with void return type.

define void @test_simplify1() {
; CHECK: @test_simplify1
%fmt = getelementptr [2 x i8]* @h, i32 0, i32 0
call void (i8*, ...)* @printf(i8* %fmt)
; CHECK-NEXT: call i32 @putchar(i32 104)
ret void
; CHECK-NEXT: ret void
}

define void @test_simplify2() {
; CHECK: @test_simplify2
%fmt = getelementptr [13 x i8]* @hello_world, i32 0, i32 0
call void (i8*, ...)* @printf(i8* %fmt)
; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([12 x i8]* @str, i32 0, i32 0))
ret void
; CHECK-NEXT: ret void
}

define void @test_simplify6() {
; CHECK: @test_simplify6
%fmt = getelementptr [4 x i8]* @percent_s, i32 0, i32 0
%str = getelementptr [13 x i8]* @hello_world, i32 0, i32 0
call void (i8*, ...)* @printf(i8* %fmt, i8* %str)
; CHECK-NEXT: call i32 @puts(i8* getelementptr inbounds ([13 x i8]* @hello_world, i32 0, i32 0))
ret void
; CHECK-NEXT: ret void
}

0 comments on commit a241b58

Please sign in to comment.