| ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 6 |
| ; RUN: opt -passes=gvn -S < %s | FileCheck %s |
| ; |
| ; The Global Value Numbering pass (GVN) propagates boolean values |
| ; that are constant in dominated basic blocks to all the uses |
| ; in these basic blocks. However, we don't want the constant propagated |
| ; into fake.use intrinsics since this would render the intrinsic useless |
| ; with respect to keeping the variable live up until the fake.use. |
| ; This test checks that we don't generate any fake.uses with constant 0. |
| ; |
| ; Reduced from the following test case, generated with clang -O2 -S -emit-llvm -fextend-variable-liveness test.c |
| ; |
| ; extern void func1(); |
| ; extern int bar(); |
| ; extern void baz(int); |
| ; |
| ; int foo(int i, float f, int *punused) |
| ; { |
| ; int j = 3*i; |
| ; if (j > 0) { |
| ; int m = bar(i); |
| ; if (m) { |
| ; char b = f; |
| ; baz(b); |
| ; if (b) |
| ; goto lab; |
| ; func1(); |
| ; } |
| ; lab: |
| ; func1(); |
| ; } |
| ; return 1; |
| ; } |
| |
| ;; GVN should propagate a constant value through to a regular call, but not to |
| ;; a fake use, which should continue to track the original value. |
| |
| define i32 @foo(float %f) optdebug { |
| ; CHECK-LABEL: define i32 @foo( |
| ; CHECK-SAME: float [[F:%.*]]) #[[ATTR0:[0-9]+]] { |
| ; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[F]] to i8 |
| ; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i8 [[CONV]], 0 |
| ; CHECK-NEXT: br i1 [[TOBOOL3]], label %[[IF_END:.*]], label %[[LAB:.*]] |
| ; CHECK: [[IF_END]]: |
| ; CHECK-NEXT: tail call void (...) @bees(i8 0) |
| ; CHECK-NEXT: tail call void (...) @llvm.fake.use(i8 [[CONV]]) |
| ; CHECK-NEXT: br label %[[LAB]] |
| ; CHECK: [[LAB]]: |
| ; CHECK-NEXT: ret i32 1 |
| ; |
| %conv = fptosi float %f to i8 |
| %tobool3 = icmp eq i8 %conv, 0 |
| br i1 %tobool3, label %if.end, label %lab |
| |
| if.end: |
| tail call void (...) @bees(i8 %conv) |
| tail call void (...) @llvm.fake.use(i8 %conv) |
| br label %lab |
| |
| lab: |
| ret i32 1 |
| } |
| |
| declare i32 @bar(...) |
| |
| declare void @baz(i32) |
| |
| declare void @bees(i32) |
| |
| declare void @func1(...) |