summaryrefslogtreecommitdiffstats
path: root/llvm/test/Transforms/NewGVN/invariant.group.ll
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/test/Transforms/NewGVN/invariant.group.ll')
-rw-r--r--llvm/test/Transforms/NewGVN/invariant.group.ll460
1 files changed, 0 insertions, 460 deletions
diff --git a/llvm/test/Transforms/NewGVN/invariant.group.ll b/llvm/test/Transforms/NewGVN/invariant.group.ll
deleted file mode 100644
index 78e61a2f2b6..00000000000
--- a/llvm/test/Transforms/NewGVN/invariant.group.ll
+++ /dev/null
@@ -1,460 +0,0 @@
-; XFAIL: *
-; RUN: opt < %s -newgvn -S | FileCheck %s
-
-%struct.A = type { i32 (...)** }
-@_ZTV1A = available_externally unnamed_addr constant [3 x i8*] [i8* null, i8* bitcast (i8** @_ZTI1A to i8*), i8* bitcast (void (%struct.A*)* @_ZN1A3fooEv to i8*)], align 8
-@_ZTI1A = external constant i8*
-
-@unknownPtr = external global i8
-
-; CHECK-LABEL: define i8 @simple() {
-define i8 @simple() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- call void @foo(i8* %ptr)
-
- %a = load i8, i8* %ptr, !invariant.group !0
- %b = load i8, i8* %ptr, !invariant.group !0
- %c = load i8, i8* %ptr, !invariant.group !0
-; CHECK: ret i8 42
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @optimizable1() {
-define i8 @optimizable1() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
- %a = load i8, i8* %ptr, !invariant.group !0
-
- call void @foo(i8* %ptr2); call to use %ptr2
-; CHECK: ret i8 42
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @optimizable2() {
-define i8 @optimizable2() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- call void @foo(i8* %ptr)
-
- store i8 13, i8* %ptr ; can't use this store with invariant.group
- %a = load i8, i8* %ptr
- call void @bar(i8 %a) ; call to use %a
-
- call void @foo(i8* %ptr)
- %b = load i8, i8* %ptr, !invariant.group !0
-
-; CHECK: ret i8 42
- ret i8 %b
-}
-
-; CHECK-LABEL: define i1 @proveEqualityForStrip(
-define i1 @proveEqualityForStrip(i8* %a) {
-; FIXME: The first call could be also removed by GVN. Right now
-; DCE removes it. The second call is CSE'd with the first one.
-; CHECK: %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
- %b1 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
-; CHECK-NOT: llvm.strip.invariant.group
- %b2 = call i8* @llvm.strip.invariant.group.p0i8(i8* %a)
- %r = icmp eq i8* %b1, %b2
-; CHECK: ret i1 true
- ret i1 %r
-}
-
-; CHECK-LABEL: define i8 @unoptimizable1() {
-define i8 @unoptimizable1() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr
- call void @foo(i8* %ptr)
- %a = load i8, i8* %ptr, !invariant.group !0
-; CHECK: ret i8 %a
- ret i8 %a
-}
-
-; CHECK-LABEL: define void @indirectLoads() {
-define void @indirectLoads() {
-entry:
- %a = alloca %struct.A*, align 8
- %0 = bitcast %struct.A** %a to i8*
-
- %call = call i8* @getPointer(i8* null)
- %1 = bitcast i8* %call to %struct.A*
- call void @_ZN1AC1Ev(%struct.A* %1)
- %2 = bitcast %struct.A* %1 to i8***
-
-; CHECK: %vtable = load {{.*}} !invariant.group
- %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
- %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
- call void @llvm.assume(i1 %cmp.vtables)
-
- store %struct.A* %1, %struct.A** %a, align 8
- %3 = load %struct.A*, %struct.A** %a, align 8
- %4 = bitcast %struct.A* %3 to void (%struct.A*)***
-
-; CHECK: call void @_ZN1A3fooEv(
- %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
- %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
- %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
- call void %5(%struct.A* %3)
- %6 = load %struct.A*, %struct.A** %a, align 8
- %7 = bitcast %struct.A* %6 to void (%struct.A*)***
-
-; CHECK: call void @_ZN1A3fooEv(
- %vtable2 = load void (%struct.A*)**, void (%struct.A*)*** %7, align 8, !invariant.group !0
- %vfn3 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable2, i64 0
- %8 = load void (%struct.A*)*, void (%struct.A*)** %vfn3, align 8
-
- call void %8(%struct.A* %6)
- %9 = load %struct.A*, %struct.A** %a, align 8
- %10 = bitcast %struct.A* %9 to void (%struct.A*)***
-
- %vtable4 = load void (%struct.A*)**, void (%struct.A*)*** %10, align 8, !invariant.group !0
- %vfn5 = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable4, i64 0
- %11 = load void (%struct.A*)*, void (%struct.A*)** %vfn5, align 8
-; CHECK: call void @_ZN1A3fooEv(
- call void %11(%struct.A* %9)
-
- %vtable5 = load i8**, i8*** %2, align 8, !invariant.group !0
- %vfn6 = getelementptr inbounds i8*, i8** %vtable5, i64 0
- %12 = bitcast i8** %vfn6 to void (%struct.A*)**
- %13 = load void (%struct.A*)*, void (%struct.A*)** %12, align 8
-; CHECK: call void @_ZN1A3fooEv(
- call void %13(%struct.A* %9)
-
- ret void
-}
-
-; CHECK-LABEL: define void @combiningBitCastWithLoad() {
-define void @combiningBitCastWithLoad() {
-entry:
- %a = alloca %struct.A*, align 8
- %0 = bitcast %struct.A** %a to i8*
-
- %call = call i8* @getPointer(i8* null)
- %1 = bitcast i8* %call to %struct.A*
- call void @_ZN1AC1Ev(%struct.A* %1)
- %2 = bitcast %struct.A* %1 to i8***
-
-; CHECK: %vtable = load {{.*}} !invariant.group
- %vtable = load i8**, i8*** %2, align 8, !invariant.group !0
- %cmp.vtables = icmp eq i8** %vtable, getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2)
-
- store %struct.A* %1, %struct.A** %a, align 8
-; CHECK-NOT: !invariant.group
- %3 = load %struct.A*, %struct.A** %a, align 8
- %4 = bitcast %struct.A* %3 to void (%struct.A*)***
-
- %vtable1 = load void (%struct.A*)**, void (%struct.A*)*** %4, align 8, !invariant.group !0
- %vfn = getelementptr inbounds void (%struct.A*)*, void (%struct.A*)** %vtable1, i64 0
- %5 = load void (%struct.A*)*, void (%struct.A*)** %vfn, align 8
- call void %5(%struct.A* %3)
-
- ret void
-}
-
-; CHECK-LABEL:define void @loadCombine() {
-define void @loadCombine() {
-enter:
- %ptr = alloca i8
- store i8 42, i8* %ptr
- call void @foo(i8* %ptr)
-; CHECK: %[[A:.*]] = load i8, i8* %ptr, !invariant.group
- %a = load i8, i8* %ptr, !invariant.group !0
-; CHECK-NOT: load
- %b = load i8, i8* %ptr, !invariant.group !0
-; CHECK: call void @bar(i8 %[[A]])
- call void @bar(i8 %a)
-; CHECK: call void @bar(i8 %[[A]])
- call void @bar(i8 %b)
- ret void
-}
-
-; CHECK-LABEL: define void @loadCombine1() {
-define void @loadCombine1() {
-enter:
- %ptr = alloca i8
- store i8 42, i8* %ptr
- call void @foo(i8* %ptr)
-; CHECK: %[[D:.*]] = load i8, i8* %ptr, !invariant.group
- %c = load i8, i8* %ptr
-; CHECK-NOT: load
- %d = load i8, i8* %ptr, !invariant.group !0
-; CHECK: call void @bar(i8 %[[D]])
- call void @bar(i8 %c)
-; CHECK: call void @bar(i8 %[[D]])
- call void @bar(i8 %d)
- ret void
-}
-
-; CHECK-LABEL: define void @loadCombine2() {
-define void @loadCombine2() {
-enter:
- %ptr = alloca i8
- store i8 42, i8* %ptr
- call void @foo(i8* %ptr)
-; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
- %e = load i8, i8* %ptr, !invariant.group !0
-; CHECK-NOT: load
- %f = load i8, i8* %ptr
-; CHECK: call void @bar(i8 %[[E]])
- call void @bar(i8 %e)
-; CHECK: call void @bar(i8 %[[E]])
- call void @bar(i8 %f)
- ret void
-}
-
-; CHECK-LABEL: define void @loadCombine3() {
-define void @loadCombine3() {
-enter:
- %ptr = alloca i8
- store i8 42, i8* %ptr
- call void @foo(i8* %ptr)
-; CHECK: %[[E:.*]] = load i8, i8* %ptr, !invariant.group
- %e = load i8, i8* %ptr, !invariant.group !0
-; CHECK-NOT: load
- %f = load i8, i8* %ptr, !invariant.group !0
-; CHECK: call void @bar(i8 %[[E]])
- call void @bar(i8 %e)
-; CHECK: call void @bar(i8 %[[E]])
- call void @bar(i8 %f)
- ret void
-}
-
-; CHECK-LABEL: define i8 @unoptimizable2() {
-define i8 @unoptimizable2() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr
- call void @foo(i8* %ptr)
- %a = load i8, i8* %ptr
- call void @foo(i8* %ptr)
- %b = load i8, i8* %ptr, !invariant.group !0
-
-; CHECK: ret i8 %a
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @unoptimizable3() {
-define i8 @unoptimizable3() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- %ptr2 = call i8* @getPointer(i8* %ptr)
- %a = load i8, i8* %ptr2, !invariant.group !0
-
-; CHECK: ret i8 %a
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @optimizable4() {
-define i8 @optimizable4() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- %ptr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
-; CHECK-NOT: load
- %a = load i8, i8* %ptr2, !invariant.group !0
-
-; CHECK: ret i8 42
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @volatile1() {
-define i8 @volatile1() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- call void @foo(i8* %ptr)
- %a = load i8, i8* %ptr, !invariant.group !0
- %b = load volatile i8, i8* %ptr
-; CHECK: call void @bar(i8 %b)
- call void @bar(i8 %b)
-
- %c = load volatile i8, i8* %ptr, !invariant.group !0
-; FIXME: we could change %c to 42, preserving volatile load
-; CHECK: call void @bar(i8 %c)
- call void @bar(i8 %c)
-; CHECK: ret i8 42
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @volatile2() {
-define i8 @volatile2() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- call void @foo(i8* %ptr)
- %a = load i8, i8* %ptr, !invariant.group !0
- %b = load volatile i8, i8* %ptr
-; CHECK: call void @bar(i8 %b)
- call void @bar(i8 %b)
-
- %c = load volatile i8, i8* %ptr, !invariant.group !0
-; FIXME: we could change %c to 42, preserving volatile load
-; CHECK: call void @bar(i8 %c)
- call void @bar(i8 %c)
-; CHECK: ret i8 42
- ret i8 %a
-}
-
-; CHECK-LABEL: define i8 @fun() {
-define i8 @fun() {
-entry:
- %ptr = alloca i8
- store i8 42, i8* %ptr, !invariant.group !0
- call void @foo(i8* %ptr)
-
- %a = load i8, i8* %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
-; CHECK: call void @bar(i8 42)
- call void @bar(i8 %a)
-
- %newPtr = call i8* @getPointer(i8* %ptr)
- %c = load i8, i8* %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
-; CHECK: call void @bar(i8 %c)
- call void @bar(i8 %c)
-
- %unknownValue = load i8, i8* @unknownPtr
-; FIXME: Can assume that %unknownValue == 42
-; CHECK: store i8 %unknownValue, i8* %ptr, !invariant.group !0
- store i8 %unknownValue, i8* %ptr, !invariant.group !0
-
- %newPtr2 = call i8* @llvm.launder.invariant.group.p0i8(i8* %ptr)
-; CHECK-NOT: load
- %d = load i8, i8* %newPtr2, !invariant.group !0
-; CHECK: ret i8 %unknownValue
- ret i8 %d
-}
-
-; This test checks if invariant.group understands gep with zeros
-; CHECK-LABEL: define void @testGEP0() {
-define void @testGEP0() {
- %a = alloca %struct.A, align 8
- %1 = bitcast %struct.A* %a to i8*
- %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
- store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !invariant.group !0
-; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a)
- call void @_ZN1A3fooEv(%struct.A* nonnull dereferenceable(8) %a) ; This call may change vptr
- %3 = load i8, i8* @unknownPtr, align 4
- %4 = icmp eq i8 %3, 0
- br i1 %4, label %_Z1gR1A.exit, label %5
-
-; This should be devirtualized by invariant.group
- %6 = bitcast %struct.A* %a to void (%struct.A*)***
- %7 = load void (%struct.A*)**, void (%struct.A*)*** %6, align 8, !invariant.group !0
- %8 = load void (%struct.A*)*, void (%struct.A*)** %7, align 8
-; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
- call void %8(%struct.A* nonnull %a)
- br label %_Z1gR1A.exit
-
-_Z1gR1A.exit: ; preds = %0, %5
- ret void
-}
-
-; Check if no optimizations are performed with global pointers.
-; FIXME: we could do the optimizations if we would check if dependency comes
-; from the same function.
-; CHECK-LABEL: define void @testGlobal() {
-define void @testGlobal() {
-; CHECK: %a = load i8, i8* @unknownPtr, !invariant.group !0
- %a = load i8, i8* @unknownPtr, !invariant.group !0
- call void @foo2(i8* @unknownPtr, i8 %a)
-; CHECK: %1 = load i8, i8* @unknownPtr, !invariant.group !0
- %1 = load i8, i8* @unknownPtr, !invariant.group !0
- call void @bar(i8 %1)
-
- %b0 = bitcast i8* @unknownPtr to i1*
- call void @fooBit(i1* %b0, i1 1)
-; Adding regex because of canonicalization of bitcasts
-; CHECK: %2 = load i1, i1* {{.*}}, !invariant.group !0
- %2 = load i1, i1* %b0, !invariant.group !0
- call void @fooBit(i1* %b0, i1 %2)
-; CHECK: %3 = load i1, i1* {{.*}}, !invariant.group !0
- %3 = load i1, i1* %b0, !invariant.group !0
- call void @fooBit(i1* %b0, i1 %3)
- ret void
-}
-; And in the case it is not global
-; CHECK-LABEL: define void @testNotGlobal() {
-define void @testNotGlobal() {
- %a = alloca i8
- call void @foo(i8* %a)
-; CHECK: %b = load i8, i8* %a, !invariant.group !0
- %b = load i8, i8* %a, !invariant.group !0
- call void @foo2(i8* %a, i8 %b)
-
- %1 = load i8, i8* %a, !invariant.group !0
-; CHECK: call void @bar(i8 %b)
- call void @bar(i8 %1)
-
- %b0 = bitcast i8* %a to i1*
- call void @fooBit(i1* %b0, i1 1)
-; CHECK: %1 = trunc i8 %b to i1
- %2 = load i1, i1* %b0, !invariant.group !0
-; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
- call void @fooBit(i1* %b0, i1 %2)
- %3 = load i1, i1* %b0, !invariant.group !0
-; CHECK-NEXT: call void @fooBit(i1* %b0, i1 %1)
- call void @fooBit(i1* %b0, i1 %3)
- ret void
-}
-
-; CHECK-LABEL: define void @handling_loops()
-define void @handling_loops() {
- %a = alloca %struct.A, align 8
- %1 = bitcast %struct.A* %a to i8*
- %2 = getelementptr inbounds %struct.A, %struct.A* %a, i64 0, i32 0
- store i32 (...)** bitcast (i8** getelementptr inbounds ([3 x i8*], [3 x i8*]* @_ZTV1A, i64 0, i64 2) to i32 (...)**), i32 (...)*** %2, align 8, !invariant.group !0
- %3 = load i8, i8* @unknownPtr, align 4
- %4 = icmp sgt i8 %3, 0
- br i1 %4, label %.lr.ph.i, label %_Z2g2R1A.exit
-
-.lr.ph.i: ; preds = %0
- %5 = bitcast %struct.A* %a to void (%struct.A*)***
- %6 = load i8, i8* @unknownPtr, align 4
- %7 = icmp sgt i8 %6, 1
- br i1 %7, label %._crit_edge.preheader, label %_Z2g2R1A.exit
-
-._crit_edge.preheader: ; preds = %.lr.ph.i
- br label %._crit_edge
-
-._crit_edge: ; preds = %._crit_edge.preheader, %._crit_edge
- %8 = phi i8 [ %10, %._crit_edge ], [ 1, %._crit_edge.preheader ]
- %.pre = load void (%struct.A*)**, void (%struct.A*)*** %5, align 8, !invariant.group !0
- %9 = load void (%struct.A*)*, void (%struct.A*)** %.pre, align 8
- ; CHECK: call void @_ZN1A3fooEv(%struct.A* nonnull %a)
- call void %9(%struct.A* nonnull %a) #3
- ; CHECK-NOT: call void %
- %10 = add nuw nsw i8 %8, 1
- %11 = load i8, i8* @unknownPtr, align 4
- %12 = icmp slt i8 %10, %11
- br i1 %12, label %._crit_edge, label %_Z2g2R1A.exit.loopexit
-
-_Z2g2R1A.exit.loopexit: ; preds = %._crit_edge
- br label %_Z2g2R1A.exit
-
-_Z2g2R1A.exit: ; preds = %_Z2g2R1A.exit.loopexit, %.lr.ph.i, %0
- ret void
-}
-
-
-declare void @foo(i8*)
-declare void @foo2(i8*, i8)
-declare void @bar(i8)
-declare i8* @getPointer(i8*)
-declare void @_ZN1A3fooEv(%struct.A*)
-declare void @_ZN1AC1Ev(%struct.A*)
-declare void @fooBit(i1*, i1)
-
-declare i8* @llvm.launder.invariant.group.p0i8(i8*)
-
-; Function Attrs: nounwind
-declare void @llvm.assume(i1 %cmp.vtables) #0
-
-
-attributes #0 = { nounwind }
-!0 = !{} \ No newline at end of file
OpenPOWER on IntegriCloud