llvm/test/Feature/OperandBundles/early-cse.ll
Sanjoy Das eecad07d00 [OperandBundles] Treat "deopt" operand bundles specially
Teach LLVM optimize to more precisely in the presence of "deopt" operand
bundles.  "deopt" operand bundles imply that the call they're attached
to is at least `readonly` (i.e. they don't imply clobber semantics), and
they don't capture their bundle operands.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@254118 91177308-0d34-0410-b5e6-96231b3b80d8
2015-11-26 01:16:05 +00:00

90 lines
2.1 KiB
LLVM

; RUN: opt -S -early-cse < %s | FileCheck %s
; While it is normally okay to do memory optimizations over calls to
; @readonly_function and @readnone_function, we cannot do that if
; they're carrying unknown operand bundles since the presence of
; unknown operand bundles implies arbitrary memory effects.
declare void @readonly_function() readonly nounwind
declare void @readnone_function() readnone nounwind
define i32 @test0(i32* %x) {
; CHECK-LABEL: @test0(
entry:
store i32 100, i32* %x
; CHECK: store i32 100, i32* %x
call void @readonly_function() [ "tag"() ]
; CHECK: call void @readonly_function()
%v = load i32, i32* %x
; CHECK: %v = load i32, i32* %x
; CHECK: ret i32 %v
ret i32 %v
}
define i32 @test1(i32* %x) {
; CHECK: @test1(
entry:
store i32 100, i32* %x
; CHECK: store i32 100, i32* %x
call void @readonly_function() readonly [ "tag"() ]
; CHECK-NOT: call void @readonly_function
%v = load i32, i32* %x
ret i32 %v
; CHECK: ret i32 100
}
define i32 @test3(i32* %x) {
; CHECK-LABEL: @test3(
entry:
store i32 100, i32* %x
; CHECK: store i32 100, i32* %x
call void @readonly_function()
; CHECK-NOT: call void @readonly_function
%v = load i32, i32* %x
ret i32 %v
; CHECK: ret i32 100
}
define void @test4(i32* %x) {
; CHECK-LABEL: @test4(
entry:
store i32 100, i32* %x
; CHECK: store i32 100, i32* %x
call void @readnone_function() [ "tag"() ]
; CHECK: call void @readnone_function
store i32 200, i32* %x
; CHECK: store i32 200, i32* %x
ret void
}
define void @test5(i32* %x) {
; CHECK-LABEL: @test5(
entry:
store i32 100, i32* %x
; CHECK-NOT: store i32 100, i32* %x
; CHECK-NOT: call void @readnone_function
call void @readnone_function() readnone [ "tag"() ]
store i32 200, i32* %x
; CHECK: store i32 200, i32* %x
ret void
}
define void @test6(i32* %x) {
; The "deopt" operand bundle does not make the call to
; @readonly_function read-write; and so the nounwind readonly call can
; be deleted.
; CHECK-LABEL: @test6(
entry:
; CHECK-NEXT: entry:
; CHECK-NEXT: store i32 200, i32* %x
; CHECK-NEXT: ret void
store i32 100, i32* %x
call void @readonly_function() [ "deopt"() ]
store i32 200, i32* %x
ret void
}