summaryrefslogtreecommitdiffstats
path: root/test/Transforms/GVN
diff options
context:
space:
mode:
authorShih-wei Liao <sliao@google.com>2010-02-10 11:10:31 -0800
committerShih-wei Liao <sliao@google.com>2010-02-10 11:10:31 -0800
commite264f62ca09a8f65c87a46d562a4d0f9ec5d457e (patch)
tree59e3d57ef656cef79afa708ae0a3daf25cd91fcf /test/Transforms/GVN
downloadexternal_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.zip
external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.gz
external_llvm-e264f62ca09a8f65c87a46d562a4d0f9ec5d457e.tar.bz2
Check in LLVM r95781.
Diffstat (limited to 'test/Transforms/GVN')
-rw-r--r--test/Transforms/GVN/2007-07-25-DominatedLoop.ll86
-rw-r--r--test/Transforms/GVN/2007-07-25-InfiniteLoop.ll14
-rw-r--r--test/Transforms/GVN/2007-07-25-Loop.ll15
-rw-r--r--test/Transforms/GVN/2007-07-25-NestedLoop.ll38
-rw-r--r--test/Transforms/GVN/2007-07-25-SinglePredecessor.ll29
-rw-r--r--test/Transforms/GVN/2007-07-26-InterlockingLoops.ll30
-rw-r--r--test/Transforms/GVN/2007-07-26-NonRedundant.ll16
-rw-r--r--test/Transforms/GVN/2007-07-26-PhiErasure.ll28
-rw-r--r--test/Transforms/GVN/2007-07-30-PredIDom.ll274
-rw-r--r--test/Transforms/GVN/2007-07-31-NoDomInherit.ll313
-rw-r--r--test/Transforms/GVN/2007-07-31-RedundantPhi.ll22
-rw-r--r--test/Transforms/GVN/2008-02-12-UndefLoad.ll20
-rw-r--r--test/Transforms/GVN/2008-02-13-NewPHI.ll22
-rw-r--r--test/Transforms/GVN/2008-02-24-NonDominatedMemcpy.ll25
-rw-r--r--test/Transforms/GVN/2008-02-26-MemCpySize.ll46
-rw-r--r--test/Transforms/GVN/2008-07-02-Unreachable.ll35
-rw-r--r--test/Transforms/GVN/2008-12-09-SelfRemove.ll26
-rw-r--r--test/Transforms/GVN/2008-12-12-RLE-Crash.ll35
-rw-r--r--test/Transforms/GVN/2008-12-14-rle-reanalyze.ll18
-rw-r--r--test/Transforms/GVN/2008-12-15-CacheVisited.ll28
-rw-r--r--test/Transforms/GVN/2009-01-21-SortInvalidation.ll55
-rw-r--r--test/Transforms/GVN/2009-01-22-SortInvalidation.ll100
-rw-r--r--test/Transforms/GVN/2009-02-17-LoadPRECrash.ll193
-rw-r--r--test/Transforms/GVN/2009-03-05-dbg.ll66
-rw-r--r--test/Transforms/GVN/2009-03-10-PREOnVoid.ll82
-rw-r--r--test/Transforms/GVN/2009-06-17-InvalidPRE.ll72
-rw-r--r--test/Transforms/GVN/2009-07-13-MemDepSortFail.ll67
-rw-r--r--test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll15
-rw-r--r--test/Transforms/GVN/basic.ll10
-rw-r--r--test/Transforms/GVN/bitcast-of-call.ll12
-rw-r--r--test/Transforms/GVN/calls-nonlocal.ll49
-rw-r--r--test/Transforms/GVN/calls-readonly.ll29
-rw-r--r--test/Transforms/GVN/condprop.ll52
-rw-r--r--test/Transforms/GVN/crash-no-aa.ll16
-rw-r--r--test/Transforms/GVN/crash.ll137
-rw-r--r--test/Transforms/GVN/dg.exp3
-rw-r--r--test/Transforms/GVN/invariant-simple.ll36
-rw-r--r--test/Transforms/GVN/lifetime-simple.ll20
-rw-r--r--test/Transforms/GVN/load-constant-mem.ll13
-rw-r--r--test/Transforms/GVN/load-pre-align.ll44
-rw-r--r--test/Transforms/GVN/local-pre.ll18
-rw-r--r--test/Transforms/GVN/lpre-call-wrap-2.ll40
-rw-r--r--test/Transforms/GVN/lpre-call-wrap.ll55
-rw-r--r--test/Transforms/GVN/mixed.ll13
-rw-r--r--test/Transforms/GVN/nonescaping-malloc.ll108
-rw-r--r--test/Transforms/GVN/null-aliases-nothing.ll20
-rw-r--r--test/Transforms/GVN/pre-basic-add.ll27
-rw-r--r--test/Transforms/GVN/pre-load.ll364
-rw-r--r--test/Transforms/GVN/pre-single-pred.ll33
-rw-r--r--test/Transforms/GVN/rle-must-alias.ll46
-rw-r--r--test/Transforms/GVN/rle-no-phi-translate.ll28
-rw-r--r--test/Transforms/GVN/rle-nonlocal.ll24
-rw-r--r--test/Transforms/GVN/rle-phi-translate.ll146
-rw-r--r--test/Transforms/GVN/rle-semidominated.ll19
-rw-r--r--test/Transforms/GVN/rle.ll534
55 files changed, 3666 insertions, 0 deletions
diff --git a/test/Transforms/GVN/2007-07-25-DominatedLoop.ll b/test/Transforms/GVN/2007-07-25-DominatedLoop.ll
new file mode 100644
index 0000000..ad580ce
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-25-DominatedLoop.ll
@@ -0,0 +1,86 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+ %struct.PerlInterpreter = type { i8 }
+@PL_sv_count = external global i32 ; <i32*> [#uses=2]
+
+define void @perl_destruct(%struct.PerlInterpreter* %sv_interp) {
+entry:
+ br i1 false, label %cond_next25, label %cond_true16
+
+cond_true16: ; preds = %entry
+ ret void
+
+cond_next25: ; preds = %entry
+ br i1 false, label %cond_next33, label %cond_true32
+
+cond_true32: ; preds = %cond_next25
+ ret void
+
+cond_next33: ; preds = %cond_next25
+ br i1 false, label %cond_next61, label %cond_true.i46
+
+cond_true.i46: ; preds = %cond_next33
+ ret void
+
+cond_next61: ; preds = %cond_next33
+ br i1 false, label %cond_next69, label %cond_true66
+
+cond_true66: ; preds = %cond_next61
+ ret void
+
+cond_next69: ; preds = %cond_next61
+ br i1 false, label %Perl_safefree.exit52, label %cond_true.i50
+
+cond_true.i50: ; preds = %cond_next69
+ ret void
+
+Perl_safefree.exit52: ; preds = %cond_next69
+ br i1 false, label %cond_next80, label %cond_true77
+
+cond_true77: ; preds = %Perl_safefree.exit52
+ ret void
+
+cond_next80: ; preds = %Perl_safefree.exit52
+ br i1 false, label %Perl_safefree.exit56, label %cond_true.i54
+
+cond_true.i54: ; preds = %cond_next80
+ ret void
+
+Perl_safefree.exit56: ; preds = %cond_next80
+ br i1 false, label %Perl_safefree.exit60, label %cond_true.i58
+
+cond_true.i58: ; preds = %Perl_safefree.exit56
+ ret void
+
+Perl_safefree.exit60: ; preds = %Perl_safefree.exit56
+ br i1 false, label %Perl_safefree.exit64, label %cond_true.i62
+
+cond_true.i62: ; preds = %Perl_safefree.exit60
+ ret void
+
+Perl_safefree.exit64: ; preds = %Perl_safefree.exit60
+ br i1 false, label %Perl_safefree.exit68, label %cond_true.i66
+
+cond_true.i66: ; preds = %Perl_safefree.exit64
+ ret void
+
+Perl_safefree.exit68: ; preds = %Perl_safefree.exit64
+ br i1 false, label %cond_next150, label %cond_true23.i
+
+cond_true23.i: ; preds = %Perl_safefree.exit68
+ ret void
+
+cond_next150: ; preds = %Perl_safefree.exit68
+ %tmp16092 = load i32* @PL_sv_count, align 4 ; <i32> [#uses=0]
+ br label %cond_next165
+
+bb157: ; preds = %cond_next165
+ %tmp158 = load i32* @PL_sv_count, align 4 ; <i32> [#uses=0]
+ br label %cond_next165
+
+cond_next165: ; preds = %bb157, %cond_next150
+ br i1 false, label %bb171, label %bb157
+
+bb171: ; preds = %cond_next165
+ ret void
+}
diff --git a/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll b/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
new file mode 100644
index 0000000..2e0a101
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
@@ -0,0 +1,14 @@
+; RUN: opt < %s -gvn -S | not grep {tmp10 =}
+
+ %struct.INT2 = type { i32, i32 }
+@blkshifts = external global %struct.INT2* ; <%struct.INT2**> [#uses=2]
+
+define i32 @xcompact() {
+entry:
+ store %struct.INT2* null, %struct.INT2** @blkshifts, align 4
+ br label %bb
+
+bb: ; preds = %bb, %entry
+ %tmp10 = load %struct.INT2** @blkshifts, align 4 ; <%struct.INT2*> [#uses=0]
+ br label %bb
+}
diff --git a/test/Transforms/GVN/2007-07-25-Loop.ll b/test/Transforms/GVN/2007-07-25-Loop.ll
new file mode 100644
index 0000000..6a9f58e
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-25-Loop.ll
@@ -0,0 +1,15 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+ %struct.s_segment_inf = type { float, i32, i16, i16, float, float, i32, float, float }
+
+define void @print_arch(i8* %arch_file, i32 %route_type, i64 %det_routing_arch.0.0, i64 %det_routing_arch.0.1, i64 %det_routing_arch.0.2, i64 %det_routing_arch.0.3, i64 %det_routing_arch.0.4, %struct.s_segment_inf* %segment_inf, i64 %timing_inf.0.0, i64 %timing_inf.0.1, i64 %timing_inf.0.2, i64 %timing_inf.0.3, i64 %timing_inf.0.4, i32 %timing_inf.1) {
+entry:
+ br i1 false, label %bb278, label %bb344
+
+bb278: ; preds = %bb278, %entry
+ br i1 false, label %bb278, label %bb344
+
+bb344: ; preds = %bb278, %entry
+ %tmp38758 = load i16* null, align 2 ; <i16> [#uses=0]
+ ret void
+}
diff --git a/test/Transforms/GVN/2007-07-25-NestedLoop.ll b/test/Transforms/GVN/2007-07-25-NestedLoop.ll
new file mode 100644
index 0000000..c6d7750
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-25-NestedLoop.ll
@@ -0,0 +1,38 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+ %struct.TypHeader = type { i32, %struct.TypHeader**, [3 x i8], i8 }
+
+define %struct.TypHeader* @LtRec(%struct.TypHeader* %hdL, %struct.TypHeader* %hdR) {
+entry:
+ br i1 false, label %bb556.preheader, label %bb534.preheader
+
+bb534.preheader: ; preds = %entry
+ ret %struct.TypHeader* null
+
+bb556.preheader: ; preds = %entry
+ %tmp56119 = getelementptr %struct.TypHeader* %hdR, i32 0, i32 0 ; <i32*> [#uses=1]
+ %tmp56220 = load i32* %tmp56119 ; <i32> [#uses=0]
+ br i1 false, label %bb.nph23, label %bb675.preheader
+
+bb.nph23: ; preds = %bb556.preheader
+ ret %struct.TypHeader* null
+
+bb656: ; preds = %bb675.outer, %bb656
+ %tmp678 = load i32* %tmp677 ; <i32> [#uses=0]
+ br i1 false, label %bb684, label %bb656
+
+bb684: ; preds = %bb675.outer, %bb656
+ br i1 false, label %bb924.preheader, label %bb675.outer
+
+bb675.outer: ; preds = %bb675.preheader, %bb684
+ %tmp67812 = load i32* %tmp67711 ; <i32> [#uses=0]
+ br i1 false, label %bb684, label %bb656
+
+bb675.preheader: ; preds = %bb556.preheader
+ %tmp67711 = getelementptr %struct.TypHeader* %hdR, i32 0, i32 0 ; <i32*> [#uses=1]
+ %tmp677 = getelementptr %struct.TypHeader* %hdR, i32 0, i32 0 ; <i32*> [#uses=1]
+ br label %bb675.outer
+
+bb924.preheader: ; preds = %bb684
+ ret %struct.TypHeader* null
+}
diff --git a/test/Transforms/GVN/2007-07-25-SinglePredecessor.ll b/test/Transforms/GVN/2007-07-25-SinglePredecessor.ll
new file mode 100644
index 0000000..ecff657
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-25-SinglePredecessor.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+ %struct.ggBRDF = type { i32 (...)** }
+ %struct.ggBox3 = type { %struct.ggPoint3, %struct.ggPoint3 }
+ %struct.ggMaterialRecord = type { %struct.ggPoint2, %struct.ggBox3, %struct.ggBox3, %struct.ggSpectrum, %struct.ggSpectrum, %struct.ggSpectrum, %struct.ggBRDF*, i32, i32, i32, i32 }
+ %struct.ggONB3 = type { %struct.ggPoint3, %struct.ggPoint3, %struct.ggPoint3 }
+ %struct.ggPoint2 = type { [2 x double] }
+ %struct.ggPoint3 = type { [3 x double] }
+ %struct.ggSpectrum = type { [8 x float] }
+ %struct.mrViewingHitRecord = type { double, %struct.ggPoint3, %struct.ggONB3, %struct.ggPoint2, double, %struct.ggSpectrum, %struct.ggSpectrum, i32, i32, i32, i32 }
+ %struct.mrXEllipticalCylinder = type { %struct.ggBRDF, float, float, float, float, float, float }
+
+define i32 @_ZNK21mrZEllipticalCylinder10viewingHitERK6ggRay3dddR18mrViewingHitRecordR16ggMaterialRecord(%struct.mrXEllipticalCylinder* %this, %struct.ggBox3* %ray, double %unnamed_arg, double %tmin, double %tmax, %struct.mrViewingHitRecord* %VHR, %struct.ggMaterialRecord* %unnamed_arg2) {
+entry:
+ %tmp80.i = getelementptr %struct.mrViewingHitRecord* %VHR, i32 0, i32 1, i32 0, i32 0 ; <double*> [#uses=1]
+ store double 0.000000e+00, double* %tmp80.i
+ br i1 false, label %return, label %cond_next.i
+
+cond_next.i: ; preds = %entry
+ br i1 false, label %return, label %cond_true
+
+cond_true: ; preds = %cond_next.i
+ %tmp3.i8 = getelementptr %struct.mrViewingHitRecord* %VHR, i32 0, i32 1, i32 0, i32 0 ; <double*> [#uses=1]
+ %tmp46 = load double* %tmp3.i8 ; <double> [#uses=0]
+ ret i32 1
+
+return: ; preds = %cond_next.i, %entry
+ ret i32 0
+}
diff --git a/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll b/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
new file mode 100644
index 0000000..0be3379
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
@@ -0,0 +1,30 @@
+; RUN: opt < %s -gvn -S | grep {tmp17625.* = phi i32. }
+; RUN: opt < %s -gvn -S | grep {tmp17631.* = phi i32. }
+
+@last = external global [65 x i32*] ; <[65 x i32*]*> [#uses=1]
+
+define i32 @NextRootMove(i32 %wtm) {
+cond_next95: ; preds = %cond_true85, %cond_true79, %cond_true73, %bb68
+ %tmp17618 = load i32** getelementptr ([65 x i32*]* @last, i32 0, i32 1), align 4 ; <i32*> [#uses=0]
+ br label %cond_true116
+
+cond_true116: ; preds = %cond_true111
+ br i1 false, label %cond_true128, label %cond_true145
+
+cond_true128: ; preds = %cond_true121
+ %tmp17625 = load i32** getelementptr ([65 x i32*]* @last, i32 0, i32 1), align 4 ; <i32*> [#uses=0]
+ br i1 false, label %bb98.backedge, label %return.loopexit
+
+bb98.backedge: ; preds = %bb171, %cond_true145, %cond_true128
+ br label %cond_true116
+
+cond_true145: ; preds = %cond_false
+ %tmp17631 = load i32** getelementptr ([65 x i32*]* @last, i32 0, i32 1), align 4 ; <i32*> [#uses=0]
+ br i1 false, label %bb98.backedge, label %return.loopexit
+
+return.loopexit: ; preds = %bb171, %cond_true145, %cond_true128
+ br label %return
+
+return: ; preds = %return.loopexit, %cond_next95, %cond_true85
+ ret i32 0
+}
diff --git a/test/Transforms/GVN/2007-07-26-NonRedundant.ll b/test/Transforms/GVN/2007-07-26-NonRedundant.ll
new file mode 100644
index 0000000..7579e8a
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-26-NonRedundant.ll
@@ -0,0 +1,16 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+@bsLive = external global i32 ; <i32*> [#uses=2]
+
+define i32 @bsR(i32 %n) {
+entry:
+ br i1 false, label %cond_next, label %bb19
+
+cond_next: ; preds = %entry
+ store i32 0, i32* @bsLive, align 4
+ br label %bb19
+
+bb19: ; preds = %cond_next, %entry
+ %tmp29 = load i32* @bsLive, align 4 ; <i32> [#uses=0]
+ ret i32 0
+}
diff --git a/test/Transforms/GVN/2007-07-26-PhiErasure.ll b/test/Transforms/GVN/2007-07-26-PhiErasure.ll
new file mode 100644
index 0000000..d898ab8
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-26-PhiErasure.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -gvn -S | not grep phi
+
+ %struct..0anon = type { i32 }
+ %struct.FILE = type { i8*, i32, i32, i16, i16, %struct.__sbuf, i32, i8*, i32 (i8*)*, i32 (i8*, i8*, i32)*, i64 (i8*, i64, i32)*, i32 (i8*, i8*, i32)*, %struct.__sbuf, %struct.__sFILEX*, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+ %struct.__sFILEX = type opaque
+ %struct.__sbuf = type { i8*, i32 }
+ %struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
+@n_spills = external global i32 ; <i32*> [#uses=2]
+
+define i32 @reload(%struct.rtx_def* %first, i32 %global, %struct.FILE* %dumpfile) {
+cond_next2835.1: ; preds = %cond_next2861
+ %tmp2922 = load i32* @n_spills, align 4 ; <i32> [#uses=0]
+ br label %bb2928
+
+bb2928: ; preds = %cond_next2835.1, %cond_next2943
+ br i1 false, label %cond_next2943, label %cond_true2935
+
+cond_true2935: ; preds = %bb2928
+ br label %cond_next2943
+
+cond_next2943: ; preds = %cond_true2935, %bb2928
+ br i1 false, label %bb2982.preheader, label %bb2928
+
+bb2982.preheader: ; preds = %cond_next2943
+ %tmp298316 = load i32* @n_spills, align 4 ; <i32> [#uses=0]
+ ret i32 %tmp298316
+
+}
diff --git a/test/Transforms/GVN/2007-07-30-PredIDom.ll b/test/Transforms/GVN/2007-07-30-PredIDom.ll
new file mode 100644
index 0000000..5cb6bb3
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-30-PredIDom.ll
@@ -0,0 +1,274 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+ %"struct.Block::$_16" = type { i32 }
+ %struct.Exp = type { %struct.Exp_*, i32, i32, i32, %struct.Exp*, %struct.Exp*, %"struct.Exp::$_10", %"struct.Block::$_16", %"struct.Exp::$_12" }
+ %"struct.Exp::$_10" = type { %struct.Exp* }
+ %"struct.Exp::$_12" = type { %struct.Exp** }
+ %struct.Exp_ = type { i32, i32, i32, i32, %struct.Id* }
+ %struct.Id = type { i8*, i32, i32, i32, %"struct.Id::$_13" }
+ %"struct.Id::$_13" = type { double }
+
+define i8* @_ZN3Exp8toStringEj(%struct.Exp* %this, i32 %nextpc) {
+entry:
+ switch i32 0, label %bb970 [
+ i32 1, label %bb
+ i32 2, label %bb39
+ i32 3, label %bb195
+ i32 4, label %bb270
+ i32 5, label %bb418
+ i32 6, label %bb633
+ i32 7, label %bb810
+ i32 8, label %bb882
+ i32 9, label %bb925
+ ]
+
+bb: ; preds = %entry
+ store i8* null, i8** null
+ br label %return
+
+bb39: ; preds = %entry
+ br i1 false, label %cond_true, label %cond_false132
+
+cond_true: ; preds = %bb39
+ br i1 false, label %cond_true73, label %cond_false
+
+cond_true73: ; preds = %cond_true
+ br i1 false, label %cond_true108, label %cond_next
+
+cond_true108: ; preds = %cond_true73
+ br label %cond_next
+
+cond_next: ; preds = %cond_true108, %cond_true73
+ br label %cond_next131
+
+cond_false: ; preds = %cond_true
+ br label %cond_next131
+
+cond_next131: ; preds = %cond_false, %cond_next
+ br label %cond_next141
+
+cond_false132: ; preds = %bb39
+ br label %cond_next141
+
+cond_next141: ; preds = %cond_false132, %cond_next131
+ br i1 false, label %cond_true169, label %cond_false175
+
+cond_true169: ; preds = %cond_next141
+ br label %cond_next181
+
+cond_false175: ; preds = %cond_next141
+ br label %cond_next181
+
+cond_next181: ; preds = %cond_false175, %cond_true169
+ br i1 false, label %cond_true189, label %cond_next191
+
+cond_true189: ; preds = %cond_next181
+ br label %cond_next191
+
+cond_next191: ; preds = %cond_true189, %cond_next181
+ store i8* null, i8** null
+ br label %return
+
+bb195: ; preds = %entry
+ br i1 false, label %cond_true248, label %cond_false250
+
+cond_true248: ; preds = %bb195
+ br label %cond_next252
+
+cond_false250: ; preds = %bb195
+ br label %cond_next252
+
+cond_next252: ; preds = %cond_false250, %cond_true248
+ br i1 false, label %cond_true265, label %cond_next267
+
+cond_true265: ; preds = %cond_next252
+ br label %cond_next267
+
+cond_next267: ; preds = %cond_true265, %cond_next252
+ store i8* null, i8** null
+ br label %return
+
+bb270: ; preds = %entry
+ br i1 false, label %cond_true338, label %cond_false340
+
+cond_true338: ; preds = %bb270
+ br label %cond_next342
+
+cond_false340: ; preds = %bb270
+ br label %cond_next342
+
+cond_next342: ; preds = %cond_false340, %cond_true338
+ br i1 false, label %cond_true362, label %cond_false364
+
+cond_true362: ; preds = %cond_next342
+ br label %cond_next366
+
+cond_false364: ; preds = %cond_next342
+ br label %cond_next366
+
+cond_next366: ; preds = %cond_false364, %cond_true362
+ br i1 false, label %cond_true393, label %cond_next395
+
+cond_true393: ; preds = %cond_next366
+ br label %cond_next395
+
+cond_next395: ; preds = %cond_true393, %cond_next366
+ br i1 false, label %cond_true406, label %cond_next408
+
+cond_true406: ; preds = %cond_next395
+ br label %cond_next408
+
+cond_next408: ; preds = %cond_true406, %cond_next395
+ br i1 false, label %cond_true413, label %cond_next415
+
+cond_true413: ; preds = %cond_next408
+ br label %cond_next415
+
+cond_next415: ; preds = %cond_true413, %cond_next408
+ store i8* null, i8** null
+ br label %return
+
+bb418: ; preds = %entry
+ br i1 false, label %cond_true512, label %cond_false514
+
+cond_true512: ; preds = %bb418
+ br label %cond_next516
+
+cond_false514: ; preds = %bb418
+ br label %cond_next516
+
+cond_next516: ; preds = %cond_false514, %cond_true512
+ br i1 false, label %cond_true536, label %cond_false538
+
+cond_true536: ; preds = %cond_next516
+ br label %cond_next540
+
+cond_false538: ; preds = %cond_next516
+ br label %cond_next540
+
+cond_next540: ; preds = %cond_false538, %cond_true536
+ br i1 false, label %cond_true560, label %cond_false562
+
+cond_true560: ; preds = %cond_next540
+ br label %cond_next564
+
+cond_false562: ; preds = %cond_next540
+ br label %cond_next564
+
+cond_next564: ; preds = %cond_false562, %cond_true560
+ br i1 false, label %cond_true597, label %cond_next599
+
+cond_true597: ; preds = %cond_next564
+ br label %cond_next599
+
+cond_next599: ; preds = %cond_true597, %cond_next564
+ br i1 false, label %cond_true614, label %cond_next616
+
+cond_true614: ; preds = %cond_next599
+ br label %cond_next616
+
+cond_next616: ; preds = %cond_true614, %cond_next599
+ br i1 false, label %cond_true621, label %cond_next623
+
+cond_true621: ; preds = %cond_next616
+ br label %cond_next623
+
+cond_next623: ; preds = %cond_true621, %cond_next616
+ br i1 false, label %cond_true628, label %cond_next630
+
+cond_true628: ; preds = %cond_next623
+ br label %cond_next630
+
+cond_next630: ; preds = %cond_true628, %cond_next623
+ store i8* null, i8** null
+ br label %return
+
+bb633: ; preds = %entry
+ br i1 false, label %cond_true667, label %cond_next669
+
+cond_true667: ; preds = %bb633
+ br label %cond_next669
+
+cond_next669: ; preds = %cond_true667, %bb633
+ br i1 false, label %cond_true678, label %cond_next791
+
+cond_true678: ; preds = %cond_next669
+ br label %bb735
+
+bb679: ; preds = %bb735
+ br i1 false, label %cond_true729, label %cond_next731
+
+cond_true729: ; preds = %bb679
+ br label %cond_next731
+
+cond_next731: ; preds = %cond_true729, %bb679
+ br label %bb735
+
+bb735: ; preds = %cond_next731, %cond_true678
+ br i1 false, label %bb679, label %bb743
+
+bb743: ; preds = %bb735
+ br i1 false, label %cond_true788, label %cond_next790
+
+cond_true788: ; preds = %bb743
+ br label %cond_next790
+
+cond_next790: ; preds = %cond_true788, %bb743
+ br label %cond_next791
+
+cond_next791: ; preds = %cond_next790, %cond_next669
+ br i1 false, label %cond_true805, label %cond_next807
+
+cond_true805: ; preds = %cond_next791
+ br label %cond_next807
+
+cond_next807: ; preds = %cond_true805, %cond_next791
+ store i8* null, i8** null
+ br label %return
+
+bb810: ; preds = %entry
+ br i1 false, label %cond_true870, label %cond_next872
+
+cond_true870: ; preds = %bb810
+ br label %cond_next872
+
+cond_next872: ; preds = %cond_true870, %bb810
+ br i1 false, label %cond_true877, label %cond_next879
+
+cond_true877: ; preds = %cond_next872
+ br label %cond_next879
+
+cond_next879: ; preds = %cond_true877, %cond_next872
+ store i8* null, i8** null
+ br label %return
+
+bb882: ; preds = %entry
+ br i1 false, label %cond_true920, label %cond_next922
+
+cond_true920: ; preds = %bb882
+ br label %cond_next922
+
+cond_next922: ; preds = %cond_true920, %bb882
+ store i8* null, i8** null
+ br label %return
+
+bb925: ; preds = %entry
+ br i1 false, label %cond_true965, label %cond_next967
+
+cond_true965: ; preds = %bb925
+ br label %cond_next967
+
+cond_next967: ; preds = %cond_true965, %bb925
+ store i8* null, i8** null
+ br label %return
+
+bb970: ; preds = %entry
+ unreachable
+ ; No predecessors!
+ store i8* null, i8** null
+ br label %return
+
+return: ; preds = %0, %cond_next967, %cond_next922, %cond_next879, %cond_next807, %cond_next630, %cond_next415, %cond_next267, %cond_next191, %bb
+ %retval980 = load i8** null ; <i8*> [#uses=1]
+ ret i8* %retval980
+}
diff --git a/test/Transforms/GVN/2007-07-31-NoDomInherit.ll b/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
new file mode 100644
index 0000000..faa1157
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
@@ -0,0 +1,313 @@
+; RUN: opt < %s -gvn -S | grep {tmp47 = phi i32 }
+
+ %struct.anon = type { i32 (i32, i32, i32)*, i32, i32, [3 x i32], i8*, i8*, i8* }
+@debug = external constant i32 ; <i32*> [#uses=0]
+@counters = external constant i32 ; <i32*> [#uses=1]
+@trialx = external global [17 x i32] ; <[17 x i32]*> [#uses=1]
+@dummy1 = external global [7 x i32] ; <[7 x i32]*> [#uses=0]
+@dummy2 = external global [4 x i32] ; <[4 x i32]*> [#uses=0]
+@unacceptable = external global i32 ; <i32*> [#uses=0]
+@isa = external global [13 x %struct.anon] ; <[13 x %struct.anon]*> [#uses=3]
+@.str = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str1 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str2 = external constant [1 x i8] ; <[1 x i8]*> [#uses=0]
+@.str3 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str4 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str5 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str6 = external constant [2 x i8] ; <[2 x i8]*> [#uses=0]
+@.str7 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str8 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str9 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str10 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str11 = external constant [2 x i8] ; <[2 x i8]*> [#uses=0]
+@.str12 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str13 = external constant [2 x i8] ; <[2 x i8]*> [#uses=0]
+@.str14 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+@.str15 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+@.str16 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str17 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str18 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str19 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str20 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str21 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str22 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str23 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+@.str24 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str25 = external constant [6 x i8] ; <[6 x i8]*> [#uses=0]
+@.str26 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+@.str27 = external constant [6 x i8] ; <[6 x i8]*> [#uses=0]
+@r = external global [17 x i32] ; <[17 x i32]*> [#uses=0]
+@.str28 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str29 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+@pgm = external global [5 x { i32, [3 x i32] }] ; <[5 x { i32, [3 x i32] }]*> [#uses=4]
+@.str30 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str31 = external constant [13 x i8] ; <[13 x i8]*> [#uses=0]
+@.str32 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str33 = external constant [4 x i8] ; <[4 x i8]*> [#uses=0]
+@.str34 = external constant [20 x i8] ; <[20 x i8]*> [#uses=0]
+@numi = external global i32 ; <i32*> [#uses=7]
+@.str35 = external constant [10 x i8] ; <[10 x i8]*> [#uses=0]
+@counter = external global [5 x i32] ; <[5 x i32]*> [#uses=2]
+@itrialx.2510 = external global i32 ; <i32*> [#uses=0]
+@.str36 = external constant [43 x i8] ; <[43 x i8]*> [#uses=0]
+@.str37 = external constant [42 x i8] ; <[42 x i8]*> [#uses=0]
+@corr_result = external global i32 ; <i32*> [#uses=0]
+@.str38 = external constant [3 x i8] ; <[3 x i8]*> [#uses=0]
+@.str39 = external constant [5 x i8] ; <[5 x i8]*> [#uses=0]
+@.str40 = external constant [47 x i8] ; <[47 x i8]*> [#uses=0]
+@correct_result = external global [17 x i32] ; <[17 x i32]*> [#uses=1]
+@.str41 = external constant [46 x i8] ; <[46 x i8]*> [#uses=0]
+@.str42 = external constant [32 x i8] ; <[32 x i8]*> [#uses=0]
+@.str43 = external constant [44 x i8] ; <[44 x i8]*> [#uses=1]
+@.str44 = external constant [21 x i8] ; <[21 x i8]*> [#uses=1]
+@.str45 = external constant [12 x i8] ; <[12 x i8]*> [#uses=1]
+@.str46 = external constant [5 x i8] ; <[5 x i8]*> [#uses=1]
+@.str47 = external constant [12 x i8] ; <[12 x i8]*> [#uses=1]
+
+declare i32 @neg(i32, i32, i32)
+
+declare i32 @Not(i32, i32, i32)
+
+declare i32 @pop(i32, i32, i32)
+
+declare i32 @nlz(i32, i32, i32)
+
+declare i32 @rev(i32, i32, i32)
+
+declare i32 @add(i32, i32, i32)
+
+declare i32 @sub(i32, i32, i32)
+
+declare i32 @mul(i32, i32, i32)
+
+declare i32 @divide(i32, i32, i32)
+
+declare i32 @divu(i32, i32, i32)
+
+declare i32 @And(i32, i32, i32)
+
+declare i32 @Or(i32, i32, i32)
+
+declare i32 @Xor(i32, i32, i32)
+
+declare i32 @rotl(i32, i32, i32)
+
+declare i32 @shl(i32, i32, i32)
+
+declare i32 @shr(i32, i32, i32)
+
+declare i32 @shrs(i32, i32, i32)
+
+declare i32 @cmpeq(i32, i32, i32)
+
+declare i32 @cmplt(i32, i32, i32)
+
+declare i32 @cmpltu(i32, i32, i32)
+
+declare i32 @seleq(i32, i32, i32)
+
+declare i32 @sellt(i32, i32, i32)
+
+declare i32 @selle(i32, i32, i32)
+
+declare void @print_expr(i32)
+
+declare i32 @printf(i8*, ...)
+
+declare i32 @putchar(i32)
+
+declare void @print_pgm()
+
+declare void @simulate_one_instruction(i32)
+
+declare i32 @check(i32)
+
+declare i32 @puts(i8*)
+
+declare void @fix_operands(i32)
+
+declare void @abort()
+
+declare i32 @increment()
+
+declare i32 @search()
+
+define i32 @main(i32 %argc, i8** %argv) {
+entry:
+ %argc_addr = alloca i32 ; <i32*> [#uses=1]
+ %argv_addr = alloca i8** ; <i8***> [#uses=1]
+ %retval = alloca i32, align 4 ; <i32*> [#uses=2]
+ %tmp = alloca i32, align 4 ; <i32*> [#uses=2]
+ %i = alloca i32, align 4 ; <i32*> [#uses=21]
+ %num_sol = alloca i32, align 4 ; <i32*> [#uses=4]
+ %total = alloca i32, align 4 ; <i32*> [#uses=4]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i32 %argc, i32* %argc_addr
+ store i8** %argv, i8*** %argv_addr
+ store i32 0, i32* %num_sol
+ store i32 1, i32* @numi
+ br label %bb91
+
+bb: ; preds = %cond_next97
+ %tmp1 = load i32* @numi ; <i32> [#uses=1]
+ %tmp2 = getelementptr [44 x i8]* @.str43, i32 0, i32 0 ; <i8*> [#uses=1]
+ %tmp3 = call i32 (i8*, ...)* @printf( i8* %tmp2, i32 %tmp1 ) ; <i32> [#uses=0]
+ store i32 0, i32* %i
+ br label %bb13
+
+bb4: ; preds = %bb13
+ %tmp5 = load i32* %i ; <i32> [#uses=1]
+ %tmp6 = load i32* %i ; <i32> [#uses=1]
+ %tmp7 = getelementptr [17 x i32]* @trialx, i32 0, i32 %tmp6 ; <i32*> [#uses=1]
+ %tmp8 = load i32* %tmp7 ; <i32> [#uses=1]
+ %tmp9 = call i32 @userfun( i32 %tmp8 ) ; <i32> [#uses=1]
+ %tmp10 = getelementptr [17 x i32]* @correct_result, i32 0, i32 %tmp5 ; <i32*> [#uses=1]
+ store i32 %tmp9, i32* %tmp10
+ %tmp11 = load i32* %i ; <i32> [#uses=1]
+ %tmp12 = add i32 %tmp11, 1 ; <i32> [#uses=1]
+ store i32 %tmp12, i32* %i
+ br label %bb13
+
+bb13: ; preds = %bb4, %bb
+ %tmp14 = load i32* %i ; <i32> [#uses=1]
+ %tmp15 = icmp sle i32 %tmp14, 16 ; <i1> [#uses=1]
+ %tmp1516 = zext i1 %tmp15 to i32 ; <i32> [#uses=1]
+ %toBool = icmp ne i32 %tmp1516, 0 ; <i1> [#uses=1]
+ br i1 %toBool, label %bb4, label %bb17
+
+bb17: ; preds = %bb13
+ store i32 0, i32* %i
+ br label %bb49
+
+bb18: ; preds = %bb49
+ %tmp19 = load i32* %i ; <i32> [#uses=1]
+ %tmp20 = getelementptr [5 x { i32, [3 x i32] }]* @pgm, i32 0, i32 %tmp19 ; <{ i32, [3 x i32] }*> [#uses=1]
+ %tmp21 = getelementptr { i32, [3 x i32] }* %tmp20, i32 0, i32 0 ; <i32*> [#uses=1]
+ store i32 0, i32* %tmp21
+ %tmp22 = load i32* %i ; <i32> [#uses=1]
+ %tmp23 = getelementptr [13 x %struct.anon]* @isa, i32 0, i32 0 ; <%struct.anon*> [#uses=1]
+ %tmp24 = getelementptr %struct.anon* %tmp23, i32 0, i32 3 ; <[3 x i32]*> [#uses=1]
+ %tmp25 = getelementptr [3 x i32]* %tmp24, i32 0, i32 0 ; <i32*> [#uses=1]
+ %tmp26 = load i32* %tmp25 ; <i32> [#uses=1]
+ %tmp27 = getelementptr [5 x { i32, [3 x i32] }]* @pgm, i32 0, i32 %tmp22 ; <{ i32, [3 x i32] }*> [#uses=1]
+ %tmp28 = getelementptr { i32, [3 x i32] }* %tmp27, i32 0, i32 1 ; <[3 x i32]*> [#uses=1]
+ %tmp29 = getelementptr [3 x i32]* %tmp28, i32 0, i32 0 ; <i32*> [#uses=1]
+ store i32 %tmp26, i32* %tmp29
+ %tmp30 = load i32* %i ; <i32> [#uses=1]
+ %tmp31 = getelementptr [13 x %struct.anon]* @isa, i32 0, i32 0 ; <%struct.anon*> [#uses=1]
+ %tmp32 = getelementptr %struct.anon* %tmp31, i32 0, i32 3 ; <[3 x i32]*> [#uses=1]
+ %tmp33 = getelementptr [3 x i32]* %tmp32, i32 0, i32 1 ; <i32*> [#uses=1]
+ %tmp34 = load i32* %tmp33 ; <i32> [#uses=1]
+ %tmp35 = getelementptr [5 x { i32, [3 x i32] }]* @pgm, i32 0, i32 %tmp30 ; <{ i32, [3 x i32] }*> [#uses=1]
+ %tmp36 = getelementptr { i32, [3 x i32] }* %tmp35, i32 0, i32 1 ; <[3 x i32]*> [#uses=1]
+ %tmp37 = getelementptr [3 x i32]* %tmp36, i32 0, i32 1 ; <i32*> [#uses=1]
+ store i32 %tmp34, i32* %tmp37
+ %tmp38 = load i32* %i ; <i32> [#uses=1]
+ %tmp39 = getelementptr [13 x %struct.anon]* @isa, i32 0, i32 0 ; <%struct.anon*> [#uses=1]
+ %tmp40 = getelementptr %struct.anon* %tmp39, i32 0, i32 3 ; <[3 x i32]*> [#uses=1]
+ %tmp41 = getelementptr [3 x i32]* %tmp40, i32 0, i32 2 ; <i32*> [#uses=1]
+ %tmp42 = load i32* %tmp41 ; <i32> [#uses=1]
+ %tmp43 = getelementptr [5 x { i32, [3 x i32] }]* @pgm, i32 0, i32 %tmp38 ; <{ i32, [3 x i32] }*> [#uses=1]
+ %tmp44 = getelementptr { i32, [3 x i32] }* %tmp43, i32 0, i32 1 ; <[3 x i32]*> [#uses=1]
+ %tmp45 = getelementptr [3 x i32]* %tmp44, i32 0, i32 2 ; <i32*> [#uses=1]
+ store i32 %tmp42, i32* %tmp45
+ %tmp46 = load i32* %i ; <i32> [#uses=1]
+ call void @fix_operands( i32 %tmp46 )
+ %tmp47 = load i32* %i ; <i32> [#uses=1]
+ %tmp48 = add i32 %tmp47, 1 ; <i32> [#uses=1]
+ store i32 %tmp48, i32* %i
+ br label %bb49
+
+bb49: ; preds = %bb18, %bb17
+ %tmp50 = load i32* @numi ; <i32> [#uses=1]
+ %tmp51 = load i32* %i ; <i32> [#uses=1]
+ %tmp52 = icmp slt i32 %tmp51, %tmp50 ; <i1> [#uses=1]
+ %tmp5253 = zext i1 %tmp52 to i32 ; <i32> [#uses=1]
+ %toBool54 = icmp ne i32 %tmp5253, 0 ; <i1> [#uses=1]
+ br i1 %toBool54, label %bb18, label %bb55
+
+bb55: ; preds = %bb49
+ %tmp56 = call i32 @search( ) ; <i32> [#uses=1]
+ store i32 %tmp56, i32* %num_sol
+ %tmp57 = getelementptr [21 x i8]* @.str44, i32 0, i32 0 ; <i8*> [#uses=1]
+ %tmp58 = load i32* %num_sol ; <i32> [#uses=1]
+ %tmp59 = call i32 (i8*, ...)* @printf( i8* %tmp57, i32 %tmp58 ) ; <i32> [#uses=0]
+ %tmp60 = load i32* @counters ; <i32> [#uses=1]
+ %tmp61 = icmp ne i32 %tmp60, 0 ; <i1> [#uses=1]
+ %tmp6162 = zext i1 %tmp61 to i32 ; <i32> [#uses=1]
+ %toBool63 = icmp ne i32 %tmp6162, 0 ; <i1> [#uses=1]
+ br i1 %toBool63, label %cond_true, label %cond_next
+
+cond_true: ; preds = %bb55
+ store i32 0, i32* %total
+ %tmp64 = getelementptr [12 x i8]* @.str45, i32 0, i32 0 ; <i8*> [#uses=1]
+ %tmp65 = call i32 (i8*, ...)* @printf( i8* %tmp64 ) ; <i32> [#uses=0]
+ store i32 0, i32* %i
+ br label %bb79
+
+bb66: ; preds = %bb79
+ %tmp67 = load i32* %i ; <i32> [#uses=1]
+ %tmp68 = getelementptr [5 x i32]* @counter, i32 0, i32 %tmp67 ; <i32*> [#uses=1]
+ %tmp69 = load i32* %tmp68 ; <i32> [#uses=1]
+ %tmp70 = getelementptr [5 x i8]* @.str46, i32 0, i32 0 ; <i8*> [#uses=1]
+ %tmp71 = call i32 (i8*, ...)* @printf( i8* %tmp70, i32 %tmp69 ) ; <i32> [#uses=0]
+ %tmp72 = load i32* %i ; <i32> [#uses=1]
+ %tmp73 = getelementptr [5 x i32]* @counter, i32 0, i32 %tmp72 ; <i32*> [#uses=1]
+ %tmp74 = load i32* %tmp73 ; <i32> [#uses=1]
+ %tmp75 = load i32* %total ; <i32> [#uses=1]
+ %tmp76 = add i32 %tmp74, %tmp75 ; <i32> [#uses=1]
+ store i32 %tmp76, i32* %total
+ %tmp77 = load i32* %i ; <i32> [#uses=1]
+ %tmp78 = add i32 %tmp77, 1 ; <i32> [#uses=1]
+ store i32 %tmp78, i32* %i
+ br label %bb79
+
+bb79: ; preds = %bb66, %cond_true
+ %tmp80 = load i32* @numi ; <i32> [#uses=1]
+ %tmp81 = load i32* %i ; <i32> [#uses=1]
+ %tmp82 = icmp slt i32 %tmp81, %tmp80 ; <i1> [#uses=1]
+ %tmp8283 = zext i1 %tmp82 to i32 ; <i32> [#uses=1]
+ %toBool84 = icmp ne i32 %tmp8283, 0 ; <i1> [#uses=1]
+ br i1 %toBool84, label %bb66, label %bb85
+
+bb85: ; preds = %bb79
+ %tmp86 = getelementptr [12 x i8]* @.str47, i32 0, i32 0 ; <i8*> [#uses=1]
+ %tmp87 = load i32* %total ; <i32> [#uses=1]
+ %tmp88 = call i32 (i8*, ...)* @printf( i8* %tmp86, i32 %tmp87 ) ; <i32> [#uses=0]
+ br label %cond_next
+
+cond_next: ; preds = %bb85, %bb55
+ %tmp89 = load i32* @numi ; <i32> [#uses=1]
+ %tmp90 = add i32 %tmp89, 1 ; <i32> [#uses=1]
+ store i32 %tmp90, i32* @numi
+ br label %bb91
+
+bb91: ; preds = %cond_next, %entry
+ %tmp92 = load i32* @numi ; <i32> [#uses=1]
+ %tmp93 = icmp sgt i32 %tmp92, 5 ; <i1> [#uses=1]
+ %tmp9394 = zext i1 %tmp93 to i32 ; <i32> [#uses=1]
+ %toBool95 = icmp ne i32 %tmp9394, 0 ; <i1> [#uses=1]
+ br i1 %toBool95, label %cond_true96, label %cond_next97
+
+cond_true96: ; preds = %bb91
+ br label %bb102
+
+cond_next97: ; preds = %bb91
+ %tmp98 = load i32* %num_sol ; <i32> [#uses=1]
+ %tmp99 = icmp eq i32 %tmp98, 0 ; <i1> [#uses=1]
+ %tmp99100 = zext i1 %tmp99 to i32 ; <i32> [#uses=1]
+ %toBool101 = icmp ne i32 %tmp99100, 0 ; <i1> [#uses=1]
+ br i1 %toBool101, label %bb, label %bb102
+
+bb102: ; preds = %cond_next97, %cond_true96
+ store i32 0, i32* %tmp
+ %tmp103 = load i32* %tmp ; <i32> [#uses=1]
+ store i32 %tmp103, i32* %retval
+ br label %return
+
+return: ; preds = %bb102
+ %retval104 = load i32* %retval ; <i32> [#uses=1]
+ ret i32 %retval104
+}
+
+declare i32 @userfun(i32)
diff --git a/test/Transforms/GVN/2007-07-31-RedundantPhi.ll b/test/Transforms/GVN/2007-07-31-RedundantPhi.ll
new file mode 100644
index 0000000..0d1d8bc
--- /dev/null
+++ b/test/Transforms/GVN/2007-07-31-RedundantPhi.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -gvn -S | not grep {tmp701 =}
+
+@img_width = external global i16 ; <i16*> [#uses=2]
+
+define i32 @smpUMHEXBipredIntegerPelBlockMotionSearch(i16* %cur_pic, i16 signext %ref, i32 %list, i32 %pic_pix_x, i32 %pic_pix_y, i32 %blocktype, i16 signext %pred_mv_x1, i16 signext %pred_mv_y1, i16 signext %pred_mv_x2, i16 signext %pred_mv_y2, i16* %mv_x, i16* %mv_y, i16* %s_mv_x, i16* %s_mv_y, i32 %search_range, i32 %min_mcost, i32 %lambda_factor) {
+cond_next143: ; preds = %entry
+ store i16 0, i16* @img_width, align 2
+ br i1 false, label %cond_next449, label %cond_false434
+
+cond_false434: ; preds = %cond_true415
+ br label %cond_next449
+
+cond_next449: ; preds = %cond_false434, %cond_true415
+ br i1 false, label %cond_next698, label %cond_false470
+
+cond_false470: ; preds = %cond_next449
+ br label %cond_next698
+
+cond_next698: ; preds = %cond_true492
+ %tmp701 = load i16* @img_width, align 2 ; <i16> [#uses=0]
+ ret i32 0
+}
diff --git a/test/Transforms/GVN/2008-02-12-UndefLoad.ll b/test/Transforms/GVN/2008-02-12-UndefLoad.ll
new file mode 100644
index 0000000..de2aa61
--- /dev/null
+++ b/test/Transforms/GVN/2008-02-12-UndefLoad.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -gvn -S | not grep load
+; PR1996
+
+%struct.anon = type { i32, i8, i8, i8, i8 }
+
+define i32 @a() {
+entry:
+ %c = alloca %struct.anon ; <%struct.anon*> [#uses=2]
+ %tmp = getelementptr %struct.anon* %c, i32 0, i32 0 ; <i32*> [#uses=1]
+ %tmp1 = getelementptr i32* %tmp, i32 1 ; <i32*> [#uses=2]
+ %tmp2 = load i32* %tmp1, align 4 ; <i32> [#uses=1]
+ %tmp3 = or i32 %tmp2, 11 ; <i32> [#uses=1]
+ %tmp4 = and i32 %tmp3, -21 ; <i32> [#uses=1]
+ store i32 %tmp4, i32* %tmp1, align 4
+ %call = call i32 (...)* @x( %struct.anon* %c ) ; <i32> [#uses=0]
+ ret i32 undef
+}
+
+
+declare i32 @x(...)
diff --git a/test/Transforms/GVN/2008-02-13-NewPHI.ll b/test/Transforms/GVN/2008-02-13-NewPHI.ll
new file mode 100644
index 0000000..54998db
--- /dev/null
+++ b/test/Transforms/GVN/2008-02-13-NewPHI.ll
@@ -0,0 +1,22 @@
+; RUN: opt < %s -anders-aa -gvn
+; PR2032
+
+define i32 @sscal(i32 %n, double %sa1, float* %sx, i32 %incx) {
+entry:
+ %sx_addr = alloca float* ; <float**> [#uses=3]
+ store float* %sx, float** %sx_addr, align 4
+ br label %bb33
+
+bb: ; preds = %bb33
+ %tmp27 = load float** %sx_addr, align 4 ; <float*> [#uses=1]
+ store float 0.000000e+00, float* %tmp27, align 4
+ store float* null, float** %sx_addr, align 4
+ br label %bb33
+
+bb33: ; preds = %bb, %entry
+ br i1 false, label %bb, label %return
+
+return: ; preds = %bb33
+ %retval59 = load i32* null, align 4 ; <i32> [#uses=1]
+ ret i32 %retval59
+}
diff --git a/test/Transforms/GVN/2008-02-24-NonDominatedMemcpy.ll b/test/Transforms/GVN/2008-02-24-NonDominatedMemcpy.ll
new file mode 100644
index 0000000..9a75e1a
--- /dev/null
+++ b/test/Transforms/GVN/2008-02-24-NonDominatedMemcpy.ll
@@ -0,0 +1,25 @@
+; RUN: opt < %s -gvn -dse -S | grep {call.*memcpy} | count 1
+
+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"
+target triple = "x86_64-apple-darwin8"
+ %struct.ggFrame3 = type { %struct.ggPoint3, %struct.ggONB3 }
+ %struct.ggHMatrix3 = type { [4 x [4 x double]] }
+ %struct.ggONB3 = type { %struct.ggPoint3, %struct.ggPoint3, %struct.ggPoint3 }
+ %struct.ggPoint3 = type { [3 x double] }
+ %struct.ggQuaternion = type { [4 x double], i32, %struct.ggHMatrix3 }
+
+declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) nounwind
+
+define void @_Z10ggCRSplineRK8ggFrame3S1_S1_S1_d(%struct.ggFrame3* noalias sret %agg.result, %struct.ggFrame3* %f0, %struct.ggFrame3* %f1, %struct.ggFrame3* %f2, %struct.ggFrame3* %f3, double %t) nounwind {
+entry:
+ %qresult = alloca %struct.ggQuaternion ; <%struct.ggQuaternion*> [#uses=1]
+ %tmp = alloca %struct.ggONB3 ; <%struct.ggONB3*> [#uses=2]
+ call void @_ZN12ggQuaternion7getONB3Ev( %struct.ggONB3* noalias sret %tmp, %struct.ggQuaternion* %qresult ) nounwind
+ %tmp1.i = getelementptr %struct.ggFrame3* %agg.result, i32 0, i32 1 ; <%struct.ggONB3*> [#uses=1]
+ %tmp13.i = bitcast %struct.ggONB3* %tmp1.i to i8* ; <i8*> [#uses=1]
+ %tmp24.i = bitcast %struct.ggONB3* %tmp to i8* ; <i8*> [#uses=1]
+ call void @llvm.memcpy.i64( i8* %tmp13.i, i8* %tmp24.i, i64 72, i32 8 ) nounwind
+ ret void
+}
+
+declare void @_ZN12ggQuaternion7getONB3Ev(%struct.ggONB3* noalias sret , %struct.ggQuaternion*) nounwind
diff --git a/test/Transforms/GVN/2008-02-26-MemCpySize.ll b/test/Transforms/GVN/2008-02-26-MemCpySize.ll
new file mode 100644
index 0000000..6ed8a76
--- /dev/null
+++ b/test/Transforms/GVN/2008-02-26-MemCpySize.ll
@@ -0,0 +1,46 @@
+; RUN: opt < %s -gvn -dse -S | grep {call.*memcpy.*cell} | count 2
+; PR2099
+
+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"
+target triple = "i686-apple-darwin9"
+ %struct.s = type { [11 x i8], i32 }
+@.str = internal constant [11 x i8] c"0123456789\00" ; <[11 x i8]*> [#uses=1]
+@cell = weak global %struct.s zeroinitializer ; <%struct.s*> [#uses=2]
+
+declare i32 @check(%struct.s* byval %p) nounwind
+
+declare i32 @strcmp(i8*, i8*) nounwind readonly
+
+define i32 @main() noreturn nounwind {
+entry:
+ %p = alloca %struct.s, align 8 ; <%struct.s*> [#uses=2]
+ store i32 99, i32* getelementptr (%struct.s* @cell, i32 0, i32 1), align 4
+ call void @llvm.memcpy.i32( i8* getelementptr (%struct.s* @cell, i32 0, i32 0, i32 0), i8* getelementptr ([11 x i8]* @.str, i32 0, i32 0), i32 11, i32 1 )
+ %tmp = getelementptr %struct.s* %p, i32 0, i32 0, i32 0 ; <i8*> [#uses=2]
+ call void @llvm.memcpy.i64( i8* %tmp, i8* getelementptr (%struct.s* @cell, i32 0, i32 0, i32 0), i64 16, i32 8 )
+ %tmp1.i = getelementptr %struct.s* %p, i32 0, i32 1 ; <i32*> [#uses=1]
+ %tmp2.i = load i32* %tmp1.i, align 4 ; <i32> [#uses=1]
+ %tmp3.i = icmp eq i32 %tmp2.i, 99 ; <i1> [#uses=1]
+ br i1 %tmp3.i, label %bb5.i, label %bb
+
+bb5.i: ; preds = %entry
+ %tmp91.i = call i32 @strcmp( i8* %tmp, i8* getelementptr ([11 x i8]* @.str, i32 0, i32 0) ) nounwind readonly ; <i32> [#uses=1]
+ %tmp53 = icmp eq i32 %tmp91.i, 0 ; <i1> [#uses=1]
+ br i1 %tmp53, label %bb7, label %bb
+
+bb: ; preds = %bb5.i, %entry
+ call void @abort( ) noreturn nounwind
+ unreachable
+
+bb7: ; preds = %bb5.i
+ call void @exit( i32 0 ) noreturn nounwind
+ unreachable
+}
+
+declare void @llvm.memcpy.i32(i8*, i8*, i32, i32) nounwind
+
+declare void @abort() noreturn nounwind
+
+declare void @exit(i32) noreturn nounwind
+
+declare void @llvm.memcpy.i64(i8*, i8*, i64, i32) nounwind
diff --git a/test/Transforms/GVN/2008-07-02-Unreachable.ll b/test/Transforms/GVN/2008-07-02-Unreachable.ll
new file mode 100644
index 0000000..361c155
--- /dev/null
+++ b/test/Transforms/GVN/2008-07-02-Unreachable.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -gvn -S | grep {ret i8 \[%\]tmp3}
+; PR2503
+
+@g_3 = external global i8 ; <i8*> [#uses=2]
+
+define i8 @func_1() nounwind {
+entry:
+ br i1 false, label %ifelse, label %ifthen
+
+ifthen: ; preds = %entry
+ br label %ifend
+
+ifelse: ; preds = %entry
+ %tmp3 = load i8* @g_3 ; <i8> [#uses=0]
+ br label %forcond.thread
+
+forcond.thread: ; preds = %ifelse
+ br label %afterfor
+
+forcond: ; preds = %forinc
+ br i1 false, label %afterfor, label %forbody
+
+forbody: ; preds = %forcond
+ br label %forinc
+
+forinc: ; preds = %forbody
+ br label %forcond
+
+afterfor: ; preds = %forcond, %forcond.thread
+ %tmp10 = load i8* @g_3 ; <i8> [#uses=0]
+ ret i8 %tmp10
+
+ifend: ; preds = %afterfor, %ifthen
+ ret i8 0
+}
diff --git a/test/Transforms/GVN/2008-12-09-SelfRemove.ll b/test/Transforms/GVN/2008-12-09-SelfRemove.ll
new file mode 100644
index 0000000..c6833e3
--- /dev/null
+++ b/test/Transforms/GVN/2008-12-09-SelfRemove.ll
@@ -0,0 +1,26 @@
+; RUN: opt < %s -gvn -S | grep getelementptr | count 1
+
+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"
+target triple = "i386-apple-darwin9.5"
+ %struct.anon = type { i8*, i32 }
+ %struct.d_print_info = type { i32, i8*, i32, i32, %struct.d_print_template*, %struct.d_print_mod*, i32 }
+ %struct.d_print_mod = type { %struct.d_print_mod*, %struct.demangle_component*, i32, %struct.d_print_template* }
+ %struct.d_print_template = type { %struct.d_print_template*, %struct.demangle_component* }
+ %struct.demangle_component = type { i32, { %struct.anon } }
+
+define void @d_print_mod_list(%struct.d_print_info* %dpi, %struct.d_print_mod* %mods, i32 %suffix) nounwind {
+entry:
+ %0 = getelementptr %struct.d_print_info* %dpi, i32 0, i32 1 ; <i8**> [#uses=1]
+ br i1 false, label %return, label %bb
+
+bb: ; preds = %entry
+ %1 = load i8** %0, align 4 ; <i8*> [#uses=0]
+ %2 = getelementptr %struct.d_print_info* %dpi, i32 0, i32 1 ; <i8**> [#uses=0]
+ br label %bb21
+
+bb21: ; preds = %bb21, %bb
+ br label %bb21
+
+return: ; preds = %entry
+ ret void
+}
diff --git a/test/Transforms/GVN/2008-12-12-RLE-Crash.ll b/test/Transforms/GVN/2008-12-12-RLE-Crash.ll
new file mode 100644
index 0000000..da67ee7
--- /dev/null
+++ b/test/Transforms/GVN/2008-12-12-RLE-Crash.ll
@@ -0,0 +1,35 @@
+; RUN: opt < %s -gvn | llvm-dis
+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"
+target triple = "i386-apple-darwin7"
+
+define i32 @main(i32 %argc, i8** %argv) nounwind {
+entry:
+ br label %bb84
+
+bb41: ; preds = %bb82
+ %tmp = load i8* %opt.0, align 1 ; <i8> [#uses=0]
+ %tmp1 = getelementptr i8* %opt.0, i32 1 ; <i8*> [#uses=2]
+ switch i32 0, label %bb81 [
+ i32 102, label %bb82
+ i32 110, label %bb79
+ i32 118, label %bb80
+ ]
+
+bb79: ; preds = %bb41
+ br label %bb82
+
+bb80: ; preds = %bb41
+ ret i32 0
+
+bb81: ; preds = %bb41
+ ret i32 1
+
+bb82: ; preds = %bb84, %bb79, %bb41
+ %opt.0 = phi i8* [ %tmp3, %bb84 ], [ %tmp1, %bb79 ], [ %tmp1, %bb41 ] ; <i8*> [#uses=3]
+ %tmp2 = load i8* %opt.0, align 1 ; <i8> [#uses=0]
+ br i1 false, label %bb84, label %bb41
+
+bb84: ; preds = %bb82, %entry
+ %tmp3 = getelementptr i8* null, i32 1 ; <i8*> [#uses=1]
+ br label %bb82
+}
diff --git a/test/Transforms/GVN/2008-12-14-rle-reanalyze.ll b/test/Transforms/GVN/2008-12-14-rle-reanalyze.ll
new file mode 100644
index 0000000..41f76c8
--- /dev/null
+++ b/test/Transforms/GVN/2008-12-14-rle-reanalyze.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -gvn | llvm-dis
+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"
+target triple = "i386-apple-darwin7"
+@sort_value = external global [256 x i32], align 32 ; <[256 x i32]*> [#uses=2]
+
+define i32 @Quiesce(i32 %alpha, i32 %beta, i32 %wtm, i32 %ply) nounwind {
+entry:
+ br label %bb22
+
+bb22: ; preds = %bb23, %bb22, %entry
+ br i1 false, label %bb23, label %bb22
+
+bb23: ; preds = %bb23, %bb22
+ %sortv.233 = phi i32* [ getelementptr ([256 x i32]* @sort_value, i32 0, i32 0), %bb22 ], [ %sortv.2, %bb23 ] ; <i32*> [#uses=1]
+ %0 = load i32* %sortv.233, align 4 ; <i32> [#uses=0]
+ %sortv.2 = getelementptr [256 x i32]* @sort_value, i32 0, i32 0 ; <i32*> [#uses=1]
+ br i1 false, label %bb23, label %bb22
+}
diff --git a/test/Transforms/GVN/2008-12-15-CacheVisited.ll b/test/Transforms/GVN/2008-12-15-CacheVisited.ll
new file mode 100644
index 0000000..0a63f3f
--- /dev/null
+++ b/test/Transforms/GVN/2008-12-15-CacheVisited.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -gvn | llvm-dis
+; Cached results must be added to and verified against the visited sets.
+; PR3217
+
+define fastcc void @gen_field_die(i32* %decl) nounwind {
+entry:
+ br i1 false, label %bb203, label %bb202
+
+bb202: ; preds = %entry
+ unreachable
+
+bb203: ; preds = %entry
+ %tmp = getelementptr i32* %decl, i32 1 ; <i32*> [#uses=1]
+ %tmp1 = load i32* %tmp, align 4 ; <i32> [#uses=0]
+ br i1 false, label %bb207, label %bb204
+
+bb204: ; preds = %bb203
+ %tmp2 = getelementptr i32* %decl, i32 1 ; <i32*> [#uses=1]
+ br label %bb208
+
+bb207: ; preds = %bb203
+ br label %bb208
+
+bb208: ; preds = %bb207, %bb204
+ %iftmp.1374.0.in = phi i32* [ null, %bb207 ], [ %tmp2, %bb204 ] ; <i32*> [#uses=1]
+ %iftmp.1374.0 = load i32* %iftmp.1374.0.in ; <i32> [#uses=0]
+ unreachable
+}
diff --git a/test/Transforms/GVN/2009-01-21-SortInvalidation.ll b/test/Transforms/GVN/2009-01-21-SortInvalidation.ll
new file mode 100644
index 0000000..3677593
--- /dev/null
+++ b/test/Transforms/GVN/2009-01-21-SortInvalidation.ll
@@ -0,0 +1,55 @@
+; RUN: opt < %s -gvn | llvm-dis
+; PR3358
+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"
+target triple = "x86_64-unknown-linux-gnu"
+ %struct.re_pattern_buffer = type { i8*, i64, i64, i64, i8*, i8*, i64, i8 }
+ %struct.re_registers = type { i32, i32*, i32* }
+
+define fastcc i32 @byte_re_match_2_internal(%struct.re_pattern_buffer* nocapture %bufp, i8* %string1, i32 %size1, i8* %string2, i32 %size2, i32 %pos, %struct.re_registers* %regs, i32 %stop) nounwind {
+entry:
+ br label %bb159
+
+succeed_label: ; preds = %bb159
+ ret i32 0
+
+bb159: ; preds = %bb664, %bb554, %bb159, %bb159, %bb159, %entry
+ %d.0 = phi i8* [ null, %entry ], [ %d.0, %bb159 ], [ %d.0, %bb554 ], [ %d.0, %bb159 ], [ %d.0, %bb159 ], [ %d.12, %bb664 ] ; <i8*> [#uses=5]
+ switch i32 0, label %bb661 [
+ i32 0, label %bb159
+ i32 1, label %succeed_label
+ i32 13, label %bb159
+ i32 14, label %bb159
+ i32 16, label %bb411
+ i32 24, label %bb622
+ i32 28, label %bb543
+ ]
+
+bb411: ; preds = %bb411, %bb159
+ br label %bb411
+
+bb543: ; preds = %bb159
+ br i1 false, label %bb549, label %bb550
+
+bb549: ; preds = %bb543
+ br label %bb554
+
+bb550: ; preds = %bb543
+ br i1 false, label %bb554, label %bb552
+
+bb552: ; preds = %bb550
+ %0 = load i8* %d.0, align 8 ; <i8> [#uses=0]
+ br label %bb554
+
+bb554: ; preds = %bb552, %bb550, %bb549
+ br i1 false, label %bb159, label %bb661
+
+bb622: ; preds = %bb622, %bb159
+ br label %bb622
+
+bb661: ; preds = %bb554, %bb159
+ %d.12 = select i1 false, i8* null, i8* null ; <i8*> [#uses=1]
+ br label %bb664
+
+bb664: ; preds = %bb664, %bb661
+ br i1 false, label %bb159, label %bb664
+}
diff --git a/test/Transforms/GVN/2009-01-22-SortInvalidation.ll b/test/Transforms/GVN/2009-01-22-SortInvalidation.ll
new file mode 100644
index 0000000..95690a5
--- /dev/null
+++ b/test/Transforms/GVN/2009-01-22-SortInvalidation.ll
@@ -0,0 +1,100 @@
+; RUN: opt < %s -gvn | llvm-dis
+
+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"
+target triple = "i386-apple-darwin7"
+ %struct..4sPragmaType = type { i8*, i32 }
+ %struct.AggInfo = type { i8, i8, i32, %struct.ExprList*, i32, %struct.AggInfo_col*, i32, i32, i32, %struct.AggInfo_func*, i32, i32 }
+ %struct.AggInfo_col = type { %struct.Table*, i32, i32, i32, i32, %struct.Expr* }
+ %struct.AggInfo_func = type { %struct.Expr*, %struct.FuncDef*, i32, i32 }
+ %struct.AuxData = type { i8*, void (i8*)* }
+ %struct.Bitvec = type { i32, i32, i32, { [125 x i32] } }
+ %struct.BtCursor = type { %struct.Btree*, %struct.BtShared*, %struct.BtCursor*, %struct.BtCursor*, i32 (i8*, i32, i8*, i32, i8*)*, i8*, i32, %struct.MemPage*, i32, %struct.CellInfo, i8, i8, i8*, i64, i32, i8, i32* }
+ %struct.BtLock = type { %struct.Btree*, i32, i8, %struct.BtLock* }
+ %struct.BtShared = type { %struct.Pager*, %struct.sqlite3*, %struct.BtCursor*, %struct.MemPage*, i8, i8, i8, i8, i8, i8, i8, i8, i32, i16, i16, i32, i32, i32, i32, i8, i32, i8*, void (i8*)*, %struct.sqlite3_mutex*, %struct.BusyHandler, i32, %struct.BtShared*, %struct.BtLock*, %struct.Btree* }
+ %struct.Btree = type { %struct.sqlite3*, %struct.BtShared*, i8, i8, i8, i32, %struct.Btree*, %struct.Btree* }
+ %struct.BtreeMutexArray = type { i32, [11 x %struct.Btree*] }
+ %struct.BusyHandler = type { i32 (i8*, i32)*, i8*, i32 }
+ %struct.CellInfo = type { i8*, i64, i32, i32, i16, i16, i16, i16 }
+ %struct.CollSeq = type { i8*, i8, i8, i8*, i32 (i8*, i32, i8*, i32, i8*)*, void (i8*)* }
+ %struct.Column = type { i8*, %struct.Expr*, i8*, i8*, i8, i8, i8, i8 }
+ %struct.Context = type { i64, i32, %struct.Fifo }
+ %struct.CountCtx = type { i64 }
+ %struct.Cursor = type { %struct.BtCursor*, i32, i64, i64, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i64, %struct.Btree*, i32, i8*, i64, i8*, %struct.KeyInfo*, i32, i64, %struct.sqlite3_vtab_cursor*, %struct.sqlite3_module*, i32, i32, i32*, i32*, i8* }
+ %struct.Db = type { i8*, %struct.Btree*, i8, i8, i8*, void (i8*)*, %struct.Schema* }
+ %struct.Expr = type { i8, i8, i16, %struct.CollSeq*, %struct.Expr*, %struct.Expr*, %struct.ExprList*, %struct..4sPragmaType, %struct..4sPragmaType, i32, i32, %struct.AggInfo*, i32, i32, %struct.Select*, %struct.Table*, i32 }
+ %struct.ExprList = type { i32, i32, i32, %struct.ExprList_item* }
+ %struct.ExprList_item = type { %struct.Expr*, i8*, i8, i8, i8 }
+ %struct.FKey = type { %struct.Table*, %struct.FKey*, i8*, %struct.FKey*, i32, %struct.sColMap*, i8, i8, i8, i8 }
+ %struct.Fifo = type { i32, %struct.FifoPage*, %struct.FifoPage* }
+ %struct.FifoPage = type { i32, i32, i32, %struct.FifoPage*, [1 x i64] }
+ %struct.FuncDef = type { i16, i8, i8, i8, i8*, %struct.FuncDef*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*, i32, %struct.Mem**)*, void (%struct.sqlite3_context*)*, [1 x i8] }
+ %struct.Hash = type { i8, i8, i32, i32, %struct.HashElem*, %struct._ht* }
+ %struct.HashElem = type { %struct.HashElem*, %struct.HashElem*, i8*, i8*, i32 }
+ %struct.IdList = type { %struct..4sPragmaType*, i32, i32 }
+ %struct.Index = type { i8*, i32, i32*, i32*, %struct.Table*, i32, i8, i8, i8*, %struct.Index*, %struct.Schema*, i8*, i8** }
+ %struct.KeyInfo = type { %struct.sqlite3*, i8, i8, i8, i32, i8*, [1 x %struct.CollSeq*] }
+ %struct.Mem = type { %struct.CountCtx, double, %struct.sqlite3*, i8*, i32, i16, i8, i8, void (i8*)* }
+ %struct.MemPage = type { i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i16, i16, i16, i16, i16, i16, [5 x %struct._OvflCell], %struct.BtShared*, i8*, %struct.PgHdr*, i32, %struct.MemPage* }
+ %struct.Module = type { %struct.sqlite3_module*, i8*, i8*, void (i8*)* }
+ %struct.Op = type { i8, i8, i8, i8, i32, i32, i32, { i32 } }
+ %struct.Pager = type { %struct.sqlite3_vfs*, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i8, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, %struct.Bitvec*, %struct.Bitvec*, i8*, i8*, i8*, i8*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.sqlite3_file*, %struct.BusyHandler*, %struct.PagerLruList, %struct.PgHdr*, %struct.PgHdr*, %struct.PgHdr*, i64, i64, i64, i64, i64, i32, void (%struct.PgHdr*, i32)*, void (%struct.PgHdr*, i32)*, i32, %struct.PgHdr**, i8*, [16 x i8] }
+ %struct.PagerLruLink = type { %struct.PgHdr*, %struct.PgHdr* }
+ %struct.PagerLruList = type { %struct.PgHdr*, %struct.PgHdr*, %struct.PgHdr* }
+ %struct.Parse = type { %struct.sqlite3*, i32, i8*, %struct.Vdbe*, i8, i8, i8, i8, i8, i8, i8, [8 x i32], i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, [12 x i32], i32, %struct.TableLock*, i32, i32, i32, i32, i32, %struct.Expr**, i8, %struct..4sPragmaType, %struct..4sPragmaType, %struct..4sPragmaType, i8*, i8*, %struct.Table*, %struct.Trigger*, %struct.TriggerStack*, i8*, %struct..4sPragmaType, i8, %struct.Table*, i32 }
+ %struct.PgHdr = type { %struct.Pager*, i32, %struct.PgHdr*, %struct.PgHdr*, %struct.PagerLruLink, %struct.PgHdr*, i8, i8, i8, i8, i8, i16, %struct.PgHdr*, %struct.PgHdr*, i8* }
+ %struct.Schema = type { i32, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Hash, %struct.Table*, i8, i8, i16, i32, %struct.sqlite3* }
+ %struct.Select = type { %struct.ExprList*, i8, i8, i8, i8, i8, i8, i8, %struct.SrcList*, %struct.Expr*, %struct.ExprList*, %struct.Expr*, %struct.ExprList*, %struct.Select*, %struct.Select*, %struct.Select*, %struct.Expr*, %struct.Expr*, i32, i32, [3 x i32] }
+ %struct.SrcList = type { i16, i16, [1 x %struct.SrcList_item] }
+ %struct.SrcList_item = type { i8*, i8*, i8*, %struct.Table*, %struct.Select*, i8, i8, i32, %struct.Expr*, %struct.IdList*, i64 }
+ %struct.Table = type { i8*, i32, %struct.Column*, i32, %struct.Index*, i32, %struct.Select*, i32, %struct.Trigger*, %struct.FKey*, i8*, %struct.Expr*, i32, i8, i8, i8, i8, i8, i8, i8, %struct.Module*, %struct.sqlite3_vtab*, i32, i8**, %struct.Schema* }
+ %struct.TableLock = type { i32, i32, i8, i8* }
+ %struct.Trigger = type { i8*, i8*, i8, i8, %struct.Expr*, %struct.IdList*, %struct..4sPragmaType, %struct.Schema*, %struct.Schema*, %struct.TriggerStep*, %struct.Trigger* }
+ %struct.TriggerStack = type { %struct.Table*, i32, i32, i32, i32, i32, i32, %struct.Trigger*, %struct.TriggerStack* }
+ %struct.TriggerStep = type { i32, i32, %struct.Trigger*, %struct.Select*, %struct..4sPragmaType, %struct.Expr*, %struct.ExprList*, %struct.IdList*, %struct.TriggerStep*, %struct.TriggerStep* }
+ %struct.Vdbe = type { %struct.sqlite3*, %struct.Vdbe*, %struct.Vdbe*, i32, i32, %struct.Op*, i32, i32, i32*, %struct.Mem**, %struct.Mem*, i32, %struct.Cursor**, i32, %struct.Mem*, i8**, i32, i32, i32, %struct.Mem*, i32, i32, %struct.Fifo, i32, i32, %struct.Context*, i32, i32, i32, i32, i32, [25 x i32], i32, i32, i8**, i8*, %struct.Mem*, i8, i8, i8, i8, i8, i8, i32, i64, i32, %struct.BtreeMutexArray, i32, i8*, i32 }
+ %struct.VdbeFunc = type { %struct.FuncDef*, i32, [1 x %struct.AuxData] }
+ %struct._OvflCell = type { i8*, i16 }
+ %struct._ht = type { i32, %struct.HashElem* }
+ %struct.anon = type { double }
+ %struct.sColMap = type { i32, i8* }
+ %struct.sqlite3 = type { %struct.sqlite3_vfs*, i32, %struct.Db*, i32, i32, i32, i32, i8, i8, i8, i8, i32, %struct.CollSeq*, i64, i64, i32, i32, i32, %struct.sqlite3_mutex*, %struct.sqlite3InitInfo, i32, i8**, %struct.Vdbe*, i32, void (i8*, i8*)*, i8*, void (i8*, i8*, i64)*, i8*, i8*, i32 (i8*)*, i8*, void (i8*)*, i8*, void (i8*, i32, i8*, i8*, i64)*, void (i8*, %struct.sqlite3*, i32, i8*)*, void (i8*, %struct.sqlite3*, i32, i8*)*, i8*, %struct.Mem*, i8*, i8*, %struct.anon, i32 (i8*, i32, i8*, i8*, i8*, i8*)*, i8*, i32 (i8*)*, i8*, i32, %struct.Hash, %struct.Table*, %struct.sqlite3_vtab**, i32, %struct.Hash, %struct.Hash, %struct.BusyHandler, i32, [2 x %struct.Db], i8 }
+ %struct.sqlite3InitInfo = type { i32, i32, i8 }
+ %struct.sqlite3_context = type { %struct.FuncDef*, %struct.VdbeFunc*, %struct.Mem, %struct.Mem*, i32, %struct.CollSeq* }
+ %struct.sqlite3_file = type { %struct.sqlite3_io_methods* }
+ %struct.sqlite3_index_constraint = type { i32, i8, i8, i32 }
+ %struct.sqlite3_index_constraint_usage = type { i32, i8 }
+ %struct.sqlite3_index_info = type { i32, %struct.sqlite3_index_constraint*, i32, %struct.sqlite3_index_constraint_usage*, %struct.sqlite3_index_constraint_usage*, i32, i8*, i32, i32, double }
+ %struct.sqlite3_io_methods = type { i32, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i8*, i32, i64)*, i32 (%struct.sqlite3_file*, i64)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i64*)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*, i32)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*, i32, i8*)*, i32 (%struct.sqlite3_file*)*, i32 (%struct.sqlite3_file*)* }
+ %struct.sqlite3_module = type { i32, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3*, i8*, i32, i8**, %struct.sqlite3_vtab**, i8**)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_index_info*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, %struct.sqlite3_vtab_cursor**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, i32, i8*, i32, %struct.Mem**)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*)*, i32 (%struct.sqlite3_vtab_cursor*, %struct.sqlite3_context*, i32)*, i32 (%struct.sqlite3_vtab_cursor*, i64*)*, i32 (%struct.sqlite3_vtab*, i32, %struct.Mem**, i64*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*)*, i32 (%struct.sqlite3_vtab*, i32, i8*, void (%struct.sqlite3_context*, i32, %struct.Mem**)**, i8**)*, i32 (%struct.sqlite3_vtab*, i8*)* }
+ %struct.sqlite3_mutex = type opaque
+ %struct.sqlite3_vfs = type { i32, i32, i32, %struct.sqlite3_vfs*, i8*, i8*, i32 (%struct.sqlite3_vfs*, i8*, %struct.sqlite3_file*, i32, i32*)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i8*, i32)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i8*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*)*, void (%struct.sqlite3_vfs*, i32, i8*)*, i8* (%struct.sqlite3_vfs*, i8*, i8*)*, void (%struct.sqlite3_vfs*, i8*)*, i32 (%struct.sqlite3_vfs*, i32, i8*)*, i32 (%struct.sqlite3_vfs*, i32)*, i32 (%struct.sqlite3_vfs*, double*)* }
+ %struct.sqlite3_vtab = type { %struct.sqlite3_module*, i32, i8* }
+ %struct.sqlite3_vtab_cursor = type { %struct.sqlite3_vtab* }
+
+define fastcc void @sqlite3Insert(%struct.Parse* %pParse, %struct.SrcList* %pTabList, %struct.ExprList* %pList, %struct.Select* %pSelect, %struct.IdList* %pColumn, i32 %onError) nounwind {
+entry:
+ br i1 false, label %bb54, label %bb69.loopexit
+
+bb54: ; preds = %entry
+ br label %bb69.loopexit
+
+bb59: ; preds = %bb63.preheader
+ %0 = load %struct..4sPragmaType** %3, align 4 ; <%struct..4sPragmaType*> [#uses=0]
+ br label %bb65
+
+bb65: ; preds = %bb63.preheader, %bb59
+ %1 = load %struct..4sPragmaType** %4, align 4 ; <%struct..4sPragmaType*> [#uses=0]
+ br i1 false, label %bb67, label %bb63.preheader
+
+bb67: ; preds = %bb65
+ %2 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=0]
+ unreachable
+
+bb69.loopexit: ; preds = %bb54, %entry
+ %3 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=1]
+ %4 = getelementptr %struct.IdList* %pColumn, i32 0, i32 0 ; <%struct..4sPragmaType**> [#uses=1]
+ br label %bb63.preheader
+
+bb63.preheader: ; preds = %bb69.loopexit, %bb65
+ br i1 false, label %bb59, label %bb65
+}
diff --git a/test/Transforms/GVN/2009-02-17-LoadPRECrash.ll b/test/Transforms/GVN/2009-02-17-LoadPRECrash.ll
new file mode 100644
index 0000000..c2d57a1
--- /dev/null
+++ b/test/Transforms/GVN/2009-02-17-LoadPRECrash.ll
@@ -0,0 +1,193 @@
+; RUN: opt < %s -gvn -enable-load-pre -disable-output
+
+ %struct.VEC_rtx_base = type { i32, i32, [1 x %struct.rtx_def*] }
+ %struct.VEC_rtx_gc = type { %struct.VEC_rtx_base }
+ %struct.block_symbol = type { [3 x %struct.cgraph_rtl_info], %struct.object_block*, i64 }
+ %struct.cgraph_rtl_info = type { i32 }
+ %struct.object_block = type { %struct.section*, i32, i64, %struct.VEC_rtx_gc*, %struct.VEC_rtx_gc* }
+ %struct.rtvec_def = type { i32, [1 x %struct.rtx_def*] }
+ %struct.rtx_def = type { i16, i8, i8, %struct.u }
+ %struct.section = type { %struct.unnamed_section }
+ %struct.u = type { %struct.block_symbol }
+ %struct.unnamed_section = type { %struct.cgraph_rtl_info, void (i8*)*, i8*, %struct.section* }
+
+declare %struct.rtvec_def* @gen_rtvec(i32, ...)
+
+declare %struct.rtx_def* @plus_constant(%struct.rtx_def*, i64)
+
+declare %struct.rtx_def* @gen_rtx_fmt_Ei(i32, i32, %struct.rtvec_def*, i32)
+
+declare i32 @local_symbolic_operand(%struct.rtx_def*, i32)
+
+define %struct.rtx_def* @legitimize_pic_address(%struct.rtx_def* %orig, %struct.rtx_def* %reg) nounwind {
+entry:
+ %addr = alloca %struct.rtx_def* ; <%struct.rtx_def**> [#uses=5]
+ %iftmp.1532 = alloca %struct.rtx_def* ; <%struct.rtx_def**> [#uses=3]
+ store %struct.rtx_def* %orig, %struct.rtx_def** null
+ %0 = load %struct.rtx_def** null, align 4 ; <%struct.rtx_def*> [#uses=0]
+ br i1 false, label %bb96, label %bb59
+
+bb59: ; preds = %entry
+ %1 = load %struct.rtx_def** %addr, align 4 ; <%struct.rtx_def*> [#uses=1]
+ %2 = call i32 @local_symbolic_operand(%struct.rtx_def* %1, i32 0) nounwind ; <i32> [#uses=0]
+ br i1 false, label %bb96, label %bb63
+
+bb63: ; preds = %bb59
+ br i1 false, label %bb64, label %bb74
+
+bb64: ; preds = %bb63
+ br i1 false, label %bb72, label %bb65
+
+bb65: ; preds = %bb64
+ br label %bb72
+
+bb72: ; preds = %bb65, %bb64
+ br label %bb74
+
+bb74: ; preds = %bb72, %bb63
+ br i1 false, label %bb75, label %bb76
+
+bb75: ; preds = %bb74
+ br label %bb76
+
+bb76: ; preds = %bb75, %bb74
+ br i1 false, label %bb77, label %bb84
+
+bb77: ; preds = %bb76
+ %3 = getelementptr [1 x %struct.cgraph_rtl_info]* null, i32 0, i32 0 ; <%struct.cgraph_rtl_info*> [#uses=0]
+ unreachable
+
+bb84: ; preds = %bb76
+ br i1 false, label %bb85, label %bb86
+
+bb85: ; preds = %bb84
+ br label %bb87
+
+bb86: ; preds = %bb84
+ br label %bb87
+
+bb87: ; preds = %bb86, %bb85
+ %4 = call %struct.rtx_def* @gen_rtx_fmt_Ei(i32 16, i32 0, %struct.rtvec_def* null, i32 1) nounwind ; <%struct.rtx_def*> [#uses=0]
+ br i1 false, label %bb89, label %bb90
+
+bb89: ; preds = %bb87
+ br label %bb91
+
+bb90: ; preds = %bb87
+ br label %bb91
+
+bb91: ; preds = %bb90, %bb89
+ br i1 false, label %bb92, label %bb93
+
+bb92: ; preds = %bb91
+ br label %bb94
+
+bb93: ; preds = %bb91
+ br label %bb94
+
+bb94: ; preds = %bb93, %bb92
+ unreachable
+
+bb96: ; preds = %bb59, %entry
+ %5 = load %struct.rtx_def** %addr, align 4 ; <%struct.rtx_def*> [#uses=1]
+ %6 = getelementptr %struct.rtx_def* %5, i32 0, i32 0 ; <i16*> [#uses=1]
+ %7 = load i16* %6, align 2 ; <i16> [#uses=0]
+ br i1 false, label %bb147, label %bb97
+
+bb97: ; preds = %bb96
+ %8 = load %struct.rtx_def** %addr, align 4 ; <%struct.rtx_def*> [#uses=0]
+ br i1 false, label %bb147, label %bb99
+
+bb99: ; preds = %bb97
+ unreachable
+
+bb147: ; preds = %bb97, %bb96
+ %9 = load %struct.rtx_def** %addr, align 4 ; <%struct.rtx_def*> [#uses=1]
+ %10 = getelementptr %struct.rtx_def* %9, i32 0, i32 0 ; <i16*> [#uses=1]
+ %11 = load i16* %10, align 2 ; <i16> [#uses=0]
+ br i1 false, label %bb164, label %bb148
+
+bb148: ; preds = %bb147
+ br i1 false, label %bb164, label %bb149
+
+bb149: ; preds = %bb148
+ br i1 false, label %bb150, label %bb152
+
+bb150: ; preds = %bb149
+ unreachable
+
+bb152: ; preds = %bb149
+ br label %bb164
+
+bb164: ; preds = %bb152, %bb148, %bb147
+ %12 = getelementptr [1 x %struct.cgraph_rtl_info]* null, i32 0, i32 1 ; <%struct.cgraph_rtl_info*> [#uses=0]
+ br i1 false, label %bb165, label %bb166
+
+bb165: ; preds = %bb164
+ br label %bb167
+
+bb166: ; preds = %bb164
+ br label %bb167
+
+bb167: ; preds = %bb166, %bb165
+ br i1 false, label %bb211, label %bb168
+
+bb168: ; preds = %bb167
+ br i1 false, label %bb211, label %bb170
+
+bb170: ; preds = %bb168
+ br i1 false, label %bb172, label %bb181
+
+bb172: ; preds = %bb170
+ br i1 false, label %bb179, label %bb174
+
+bb174: ; preds = %bb172
+ br i1 false, label %bb177, label %bb175
+
+bb175: ; preds = %bb174
+ br i1 false, label %bb177, label %bb176
+
+bb176: ; preds = %bb175
+ br label %bb178
+
+bb177: ; preds = %bb175, %bb174
+ br label %bb178
+
+bb178: ; preds = %bb177, %bb176
+ br label %bb180
+
+bb179: ; preds = %bb172
+ br label %bb180
+
+bb180: ; preds = %bb179, %bb178
+ br label %bb181
+
+bb181: ; preds = %bb180, %bb170
+ %13 = call %struct.rtvec_def* (i32, ...)* @gen_rtvec(i32 1, %struct.rtx_def* null) nounwind ; <%struct.rtvec_def*> [#uses=0]
+ unreachable
+
+bb211: ; preds = %bb168, %bb167
+ %14 = load %struct.rtx_def** %addr, align 4 ; <%struct.rtx_def*> [#uses=0]
+ %15 = getelementptr [1 x %struct.cgraph_rtl_info]* null, i32 0, i32 0 ; <%struct.cgraph_rtl_info*> [#uses=0]
+ store %struct.rtx_def* null, %struct.rtx_def** null, align 4
+ br i1 false, label %bb212, label %bb213
+
+bb212: ; preds = %bb211
+ store %struct.rtx_def* null, %struct.rtx_def** %iftmp.1532, align 4
+ br label %bb214
+
+bb213: ; preds = %bb211
+ store %struct.rtx_def* null, %struct.rtx_def** %iftmp.1532, align 4
+ br label %bb214
+
+bb214: ; preds = %bb213, %bb212
+ %16 = bitcast %struct.block_symbol* null to [1 x %struct.cgraph_rtl_info]* ; <[1 x %struct.cgraph_rtl_info]*> [#uses=1]
+ %17 = getelementptr [1 x %struct.cgraph_rtl_info]* %16, i32 0, i32 1 ; <%struct.cgraph_rtl_info*> [#uses=0]
+ %18 = load %struct.rtx_def** %iftmp.1532, align 4 ; <%struct.rtx_def*> [#uses=0]
+ %19 = getelementptr %struct.rtx_def* null, i32 0, i32 3 ; <%struct.u*> [#uses=1]
+ %20 = getelementptr %struct.u* %19, i32 0, i32 0 ; <%struct.block_symbol*> [#uses=1]
+ %21 = bitcast %struct.block_symbol* %20 to [1 x i64]* ; <[1 x i64]*> [#uses=1]
+ %22 = getelementptr [1 x i64]* %21, i32 0, i32 0 ; <i64*> [#uses=0]
+ %23 = call %struct.rtx_def* @plus_constant(%struct.rtx_def* null, i64 0) nounwind ; <%struct.rtx_def*> [#uses=0]
+ unreachable
+}
diff --git a/test/Transforms/GVN/2009-03-05-dbg.ll b/test/Transforms/GVN/2009-03-05-dbg.ll
new file mode 100644
index 0000000..cad3312
--- /dev/null
+++ b/test/Transforms/GVN/2009-03-05-dbg.ll
@@ -0,0 +1,66 @@
+; RUN: opt < %s -gvn -disable-output
+ %llvm.dbg.compile_unit.type = type { i32, { }*, i32, i8*, i8*, i8*, i1, i1, i8*, i32 }
+@llvm.dbg.compile_unit298 = external constant %llvm.dbg.compile_unit.type ; <%llvm.dbg.compile_unit.type*> [#uses=1]
+
+declare void @llvm.dbg.stoppoint(i32, i32, { }*) nounwind
+
+define i8* @__deregister_frame_info_bases(i8* %begin) {
+entry:
+ br i1 false, label %bb17, label %bb
+
+bb: ; preds = %entry
+ br i1 false, label %bb17, label %bb6.preheader
+
+bb6.preheader: ; preds = %bb
+ br label %bb6
+
+bb3: ; preds = %bb6
+ br i1 false, label %bb4, label %bb6
+
+bb4: ; preds = %bb3
+ br label %out
+
+bb6: ; preds = %bb3, %bb6.preheader
+ br i1 false, label %bb14.loopexit, label %bb3
+
+bb8: ; preds = %bb14
+ br i1 false, label %bb9, label %bb11
+
+bb9: ; preds = %bb8
+ br i1 false, label %bb10, label %bb13
+
+bb10: ; preds = %bb9
+ br label %out
+
+bb11: ; preds = %bb8
+ br i1 false, label %bb12, label %bb13
+
+bb12: ; preds = %bb11
+ br label %out
+
+bb13: ; preds = %bb11, %bb9
+ br label %bb14
+
+bb14.loopexit: ; preds = %bb6
+ br label %bb14
+
+bb14: ; preds = %bb14.loopexit, %bb13
+ br i1 false, label %bb15.loopexit, label %bb8
+
+out: ; preds = %bb12, %bb10, %bb4
+ tail call void @llvm.dbg.stoppoint(i32 217, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit298 to { }*))
+ br i1 false, label %bb15, label %bb16
+
+bb15.loopexit: ; preds = %bb14
+ br label %bb15
+
+bb15: ; preds = %bb15.loopexit, %out
+ tail call void @llvm.dbg.stoppoint(i32 217, i32 0, { }* bitcast (%llvm.dbg.compile_unit.type* @llvm.dbg.compile_unit298 to { }*))
+ unreachable
+
+bb16: ; preds = %out
+ ret i8* null
+
+bb17: ; preds = %bb, %entry
+ ret i8* null
+}
diff --git a/test/Transforms/GVN/2009-03-10-PREOnVoid.ll b/test/Transforms/GVN/2009-03-10-PREOnVoid.ll
new file mode 100644
index 0000000..89d6a5f
--- /dev/null
+++ b/test/Transforms/GVN/2009-03-10-PREOnVoid.ll
@@ -0,0 +1,82 @@
+; RUN: opt < %s -gvn -disable-output
+; PR3775
+
+; ModuleID = 'bugpoint-reduced-simplified.bc'
+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:32:32"
+target triple = "i386-pc-linux-gnu"
+ %llvm.dbg.anchor.type = type { i32, i32 }
+ %"struct.__gnu_cxx::hash<void*>" = type <{ i8 }>
+ %struct.__sched_param = type { i32 }
+ %struct._pthread_descr_struct = type opaque
+ %struct.pthread_attr_t = type { i32, i32, %struct.__sched_param, i32, i32, i32, i32, i8*, i32 }
+ %struct.pthread_mutex_t = type { i32, i32, %struct._pthread_descr_struct*, i32, %llvm.dbg.anchor.type }
+ %"struct.std::_Rb_tree<void*,std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > >,std::_Select1st<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >,std::less<void*>,std::allocator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > > >" = type { %"struct.std::_Rb_tree<void*,std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > >,std::_Select1st<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >,std::less<void*>,std::allocator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > > >::_Rb_tree_impl<std::less<void*>,false>" }
+ %"struct.std::_Rb_tree<void*,std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > >,std::_Select1st<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >,std::less<void*>,std::allocator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > > >::_Rb_tree_impl<std::less<void*>,false>" = type { %"struct.__gnu_cxx::hash<void*>", %"struct.std::_Rb_tree_node_base", i32 }
+ %"struct.std::_Rb_tree_iterator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >" = type { %"struct.std::_Rb_tree_node_base"* }
+ %"struct.std::_Rb_tree_node_base" = type { i32, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"*, %"struct.std::_Rb_tree_node_base"* }
+ %"struct.std::pair<std::_Rb_tree_iterator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >,bool>" = type { %"struct.std::_Rb_tree_iterator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >", i8 }
+ %"struct.std::pair<void* const,void*>" = type { i8*, i8* }
+
+@_ZL20__gthrw_pthread_oncePiPFvvE = alias weak i32 (i32*, void ()*)* @pthread_once ; <i32 (i32*, void ()*)*> [#uses=0]
+@_ZL27__gthrw_pthread_getspecificj = alias weak i8* (i32)* @pthread_getspecific ; <i8* (i32)*> [#uses=0]
+@_ZL27__gthrw_pthread_setspecificjPKv = alias weak i32 (i32, i8*)* @pthread_setspecific ; <i32 (i32, i8*)*> [#uses=0]
+@_ZL22__gthrw_pthread_createPmPK16__pthread_attr_sPFPvS3_ES3_ = alias weak i32 (i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)* @pthread_create ; <i32 (i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)*> [#uses=0]
+@_ZL22__gthrw_pthread_cancelm = alias weak i32 (i32)* @pthread_cancel ; <i32 (i32)*> [#uses=0]
+@_ZL26__gthrw_pthread_mutex_lockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_lock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
+@_ZL29__gthrw_pthread_mutex_trylockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_trylock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
+@_ZL28__gthrw_pthread_mutex_unlockP15pthread_mutex_t = alias weak i32 (%struct.pthread_mutex_t*)* @pthread_mutex_unlock ; <i32 (%struct.pthread_mutex_t*)*> [#uses=0]
+@_ZL26__gthrw_pthread_mutex_initP15pthread_mutex_tPK19pthread_mutexattr_t = alias weak i32 (%struct.pthread_mutex_t*, %struct.__sched_param*)* @pthread_mutex_init ; <i32 (%struct.pthread_mutex_t*, %struct.__sched_param*)*> [#uses=0]
+@_ZL26__gthrw_pthread_key_createPjPFvPvE = alias weak i32 (i32*, void (i8*)*)* @pthread_key_create ; <i32 (i32*, void (i8*)*)*> [#uses=0]
+@_ZL26__gthrw_pthread_key_deletej = alias weak i32 (i32)* @pthread_key_delete ; <i32 (i32)*> [#uses=0]
+@_ZL30__gthrw_pthread_mutexattr_initP19pthread_mutexattr_t = alias weak i32 (%struct.__sched_param*)* @pthread_mutexattr_init ; <i32 (%struct.__sched_param*)*> [#uses=0]
+@_ZL33__gthrw_pthread_mutexattr_settypeP19pthread_mutexattr_ti = alias weak i32 (%struct.__sched_param*, i32)* @pthread_mutexattr_settype ; <i32 (%struct.__sched_param*, i32)*> [#uses=0]
+@_ZL33__gthrw_pthread_mutexattr_destroyP19pthread_mutexattr_t = alias weak i32 (%struct.__sched_param*)* @pthread_mutexattr_destroy ; <i32 (%struct.__sched_param*)*> [#uses=0]
+
+declare fastcc void @_ZNSt10_Select1stISt4pairIKPvS1_EEC1Ev() nounwind readnone
+
+define fastcc void @_ZNSt8_Rb_treeIPvSt4pairIKS0_S0_ESt10_Select1stIS3_ESt4lessIS0_ESaIS3_EE16_M_insert_uniqueERKS3_(%"struct.std::pair<std::_Rb_tree_iterator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >,bool>"* noalias nocapture sret %agg.result, %"struct.std::_Rb_tree<void*,std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > >,std::_Select1st<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > >,std::less<void*>,std::allocator<std::pair<void* const, std::vector<ShadowInfo, std::allocator<ShadowInfo> > > > >"* %this, %"struct.std::pair<void* const,void*>"* %__v) nounwind {
+entry:
+ br i1 false, label %bb7, label %bb
+
+bb: ; preds = %bb, %entry
+ br i1 false, label %bb5, label %bb
+
+bb5: ; preds = %bb
+ call fastcc void @_ZNSt10_Select1stISt4pairIKPvS1_EEC1Ev() nounwind
+ br i1 false, label %bb11, label %bb7
+
+bb7: ; preds = %bb5, %entry
+ br label %bb11
+
+bb11: ; preds = %bb7, %bb5
+ call fastcc void @_ZNSt10_Select1stISt4pairIKPvS1_EEC1Ev() nounwind
+ unreachable
+}
+
+declare i32 @pthread_once(i32*, void ()*)
+
+declare i8* @pthread_getspecific(i32)
+
+declare i32 @pthread_setspecific(i32, i8*)
+
+declare i32 @pthread_create(i32*, %struct.pthread_attr_t*, i8* (i8*)*, i8*)
+
+declare i32 @pthread_cancel(i32)
+
+declare i32 @pthread_mutex_lock(%struct.pthread_mutex_t*)
+
+declare i32 @pthread_mutex_trylock(%struct.pthread_mutex_t*)
+
+declare i32 @pthread_mutex_unlock(%struct.pthread_mutex_t*)
+
+declare i32 @pthread_mutex_init(%struct.pthread_mutex_t*, %struct.__sched_param*)
+
+declare i32 @pthread_key_create(i32*, void (i8*)*)
+
+declare i32 @pthread_key_delete(i32)
+
+declare i32 @pthread_mutexattr_init(%struct.__sched_param*)
+
+declare i32 @pthread_mutexattr_settype(%struct.__sched_param*, i32)
+
+declare i32 @pthread_mutexattr_destroy(%struct.__sched_param*)
diff --git a/test/Transforms/GVN/2009-06-17-InvalidPRE.ll b/test/Transforms/GVN/2009-06-17-InvalidPRE.ll
new file mode 100644
index 0000000..6ac6072
--- /dev/null
+++ b/test/Transforms/GVN/2009-06-17-InvalidPRE.ll
@@ -0,0 +1,72 @@
+; RUN: opt < %s -gvn -enable-load-pre -S | not grep pre1
+; GVN load pre was hoisting the loads at %13 and %16 up to bb4.outer.
+; This is invalid as it bypasses the check for %m.0.ph==null in bb4.
+; ModuleID = 'mbuf.c'
+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"
+target triple = "i386-apple-darwin9.6"
+ %struct.mbuf = type { %struct.mbuf*, %struct.mbuf*, i32, i8*, i16, i16, i32 }
+
+define void @m_adj(%struct.mbuf* %mp, i32 %req_len) nounwind optsize {
+entry:
+ %0 = icmp eq %struct.mbuf* %mp, null ; <i1> [#uses=1]
+ %1 = icmp slt i32 %req_len, 0 ; <i1> [#uses=1]
+ %or.cond = or i1 %1, %0 ; <i1> [#uses=1]
+ br i1 %or.cond, label %return, label %bb4.preheader
+
+bb4.preheader: ; preds = %entry
+ br label %bb4.outer
+
+bb2: ; preds = %bb1
+ %2 = sub i32 %len.0, %13 ; <i32> [#uses=1]
+ %3 = getelementptr %struct.mbuf* %m.0.ph, i32 0, i32 2 ; <i32*> [#uses=1]
+ store i32 0, i32* %3, align 4
+ %4 = getelementptr %struct.mbuf* %m.0.ph, i32 0, i32 0 ; <%struct.mbuf**> [#uses=1]
+ %5 = load %struct.mbuf** %4, align 4 ; <%struct.mbuf*> [#uses=1]
+ br label %bb4.outer
+
+bb4.outer: ; preds = %bb4.preheader, %bb2
+ %m.0.ph = phi %struct.mbuf* [ %5, %bb2 ], [ %mp, %bb4.preheader ] ; <%struct.mbuf*> [#uses=7]
+ %len.0.ph = phi i32 [ %2, %bb2 ], [ %req_len, %bb4.preheader ] ; <i32> [#uses=1]
+ %6 = icmp ne %struct.mbuf* %m.0.ph, null ; <i1> [#uses=1]
+ %7 = getelementptr %struct.mbuf* %m.0.ph, i32 0, i32 2 ; <i32*> [#uses=1]
+ %8 = getelementptr %struct.mbuf* %m.0.ph, i32 0, i32 2 ; <i32*> [#uses=1]
+ %9 = getelementptr %struct.mbuf* %m.0.ph, i32 0, i32 3 ; <i8**> [#uses=1]
+ %10 = getelementptr %struct.mbuf* %m.0.ph, i32 0, i32 3 ; <i8**> [#uses=1]
+ br label %bb4
+
+bb4: ; preds = %bb4.outer, %bb3
+ %len.0 = phi i32 [ 0, %bb3 ], [ %len.0.ph, %bb4.outer ] ; <i32> [#uses=6]
+ %11 = icmp sgt i32 %len.0, 0 ; <i1> [#uses=1]
+ %12 = and i1 %11, %6 ; <i1> [#uses=1]
+ br i1 %12, label %bb1, label %bb7
+
+bb1: ; preds = %bb4
+ %13 = load i32* %7, align 4 ; <i32> [#uses=3]
+ %14 = icmp sgt i32 %13, %len.0 ; <i1> [#uses=1]
+ br i1 %14, label %bb3, label %bb2
+
+bb3: ; preds = %bb1
+ %15 = sub i32 %13, %len.0 ; <i32> [#uses=1]
+ store i32 %15, i32* %8, align 4
+ %16 = load i8** %9, align 4 ; <i8*> [#uses=1]
+ %17 = getelementptr i8* %16, i32 %len.0 ; <i8*> [#uses=1]
+ store i8* %17, i8** %10, align 4
+ br label %bb4
+
+bb7: ; preds = %bb4
+ %18 = getelementptr %struct.mbuf* %mp, i32 0, i32 5 ; <i16*> [#uses=1]
+ %19 = load i16* %18, align 2 ; <i16> [#uses=1]
+ %20 = zext i16 %19 to i32 ; <i32> [#uses=1]
+ %21 = and i32 %20, 2 ; <i32> [#uses=1]
+ %22 = icmp eq i32 %21, 0 ; <i1> [#uses=1]
+ br i1 %22, label %return, label %bb8
+
+bb8: ; preds = %bb7
+ %23 = sub i32 %req_len, %len.0 ; <i32> [#uses=1]
+ %24 = getelementptr %struct.mbuf* %mp, i32 0, i32 6 ; <i32*> [#uses=1]
+ store i32 %23, i32* %24, align 4
+ ret void
+
+return: ; preds = %bb7, %entry
+ ret void
+}
diff --git a/test/Transforms/GVN/2009-07-13-MemDepSortFail.ll b/test/Transforms/GVN/2009-07-13-MemDepSortFail.ll
new file mode 100644
index 0000000..641e920
--- /dev/null
+++ b/test/Transforms/GVN/2009-07-13-MemDepSortFail.ll
@@ -0,0 +1,67 @@
+; RUN: opt < %s -gvn | llvm-dis
+; PR4256
+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:32:32"
+target triple = "i386-linux-gnu"
+ %llvm.dbg.anchor.type = type { i32, i32 }
+ %struct.cset = type { i8*, i8, i8, i32, i8* }
+ %struct.lmat = type { %struct.re_guts*, i32, %llvm.dbg.anchor.type*, i8*, i8*, i8*, i8*, i8**, i32, i8*, i8*, i8*, i8*, i8* }
+ %struct.re_guts = type { i32*, %struct.cset*, i8*, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i32, i8*, i8*, i32, i32, i32, i32, [1 x i8] }
+
+define i8* @lbackref(%struct.lmat* %m, i8* %start, i8* %stop, i32 %startst, i32 %stopst, i32 %lev, i32 %rec) nounwind {
+entry:
+ br label %bb63
+
+bb: ; preds = %bb63
+ switch i32 0, label %bb62 [
+ i32 268435456, label %bb2
+ i32 805306368, label %bb9
+ i32 -1610612736, label %bb51
+ ]
+
+bb2: ; preds = %bb
+ br label %bb62
+
+bb9: ; preds = %bb
+ %0 = load i8* %sp.1, align 1 ; <i8> [#uses=0]
+ br label %bb62
+
+bb51: ; preds = %bb
+ %1 = load i8* %sp.1, align 1 ; <i8> [#uses=0]
+ ret i8* null
+
+bb62: ; preds = %bb9, %bb2, %bb
+ br label %bb63
+
+bb63: ; preds = %bb84, %bb69, %bb62, %entry
+ %sp.1 = phi i8* [ null, %bb62 ], [ %sp.1.lcssa, %bb84 ], [ %start, %entry ], [ %sp.1.lcssa, %bb69 ] ; <i8*> [#uses=3]
+ br i1 false, label %bb, label %bb65
+
+bb65: ; preds = %bb63
+ %sp.1.lcssa = phi i8* [ %sp.1, %bb63 ] ; <i8*> [#uses=4]
+ br i1 false, label %bb66, label %bb69
+
+bb66: ; preds = %bb65
+ ret i8* null
+
+bb69: ; preds = %bb65
+ switch i32 0, label %bb108.loopexit2.loopexit.loopexit [
+ i32 1342177280, label %bb63
+ i32 1476395008, label %bb84
+ i32 1879048192, label %bb104
+ i32 2013265920, label %bb93
+ ]
+
+bb84: ; preds = %bb69
+ %2 = tail call i8* @lbackref(%struct.lmat* %m, i8* %sp.1.lcssa, i8* %stop, i32 0, i32 %stopst, i32 0, i32 0) nounwind ; <i8*> [#uses=0]
+ br label %bb63
+
+bb93: ; preds = %bb69
+ ret i8* null
+
+bb104: ; preds = %bb69
+ %sp.1.lcssa.lcssa33 = phi i8* [ %sp.1.lcssa, %bb69 ] ; <i8*> [#uses=0]
+ unreachable
+
+bb108.loopexit2.loopexit.loopexit: ; preds = %bb69
+ ret i8* null
+}
diff --git a/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll b/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll
new file mode 100644
index 0000000..b433297
--- /dev/null
+++ b/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll
@@ -0,0 +1,15 @@
+; Test to make sure malloc's bitcast does not block detection of a store
+; to aliased memory; GVN should not optimize away the load in this program.
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+define i64 @test() {
+ %1 = tail call i8* @malloc(i64 mul (i64 4, i64 ptrtoint (i64* getelementptr (i64* null, i64 1) to i64))) ; <i8*> [#uses=2]
+ store i8 42, i8* %1
+ %X = bitcast i8* %1 to i64* ; <i64*> [#uses=1]
+ %Y = load i64* %X ; <i64> [#uses=1]
+ ret i64 %Y
+; CHECK: %Y = load i64* %X
+; CHECK: ret i64 %Y
+}
+
+declare noalias i8* @malloc(i64)
diff --git a/test/Transforms/GVN/basic.ll b/test/Transforms/GVN/basic.ll
new file mode 100644
index 0000000..1decafa
--- /dev/null
+++ b/test/Transforms/GVN/basic.ll
@@ -0,0 +1,10 @@
+; RUN: opt < %s -gvn -S | not grep {%z2 =}
+
+define i32 @main() {
+block1:
+ %z1 = bitcast i32 0 to i32
+ br label %block2
+block2:
+ %z2 = bitcast i32 0 to i32
+ ret i32 %z2
+}
diff --git a/test/Transforms/GVN/bitcast-of-call.ll b/test/Transforms/GVN/bitcast-of-call.ll
new file mode 100644
index 0000000..55b4b6e
--- /dev/null
+++ b/test/Transforms/GVN/bitcast-of-call.ll
@@ -0,0 +1,12 @@
+; RUN: opt < %s -gvn -S | not grep tmp2
+; PR2213
+
+define i32* @f(i8* %x) {
+entry:
+ %tmp = call i8* @m( i32 12 ) ; <i8*> [#uses=2]
+ %tmp1 = bitcast i8* %tmp to i32* ; <i32*> [#uses=0]
+ %tmp2 = bitcast i8* %tmp to i32* ; <i32*> [#uses=0]
+ ret i32* %tmp2
+}
+
+declare i8* @m(i32)
diff --git a/test/Transforms/GVN/calls-nonlocal.ll b/test/Transforms/GVN/calls-nonlocal.ll
new file mode 100644
index 0000000..f0edf09
--- /dev/null
+++ b/test/Transforms/GVN/calls-nonlocal.ll
@@ -0,0 +1,49 @@
+; RUN: opt < %s -gvn -S | grep strlen | count 2
+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"
+target triple = "i386-apple-darwin9"
+
+define i32 @test(i32 %g, i8* %P) nounwind {
+entry:
+ %tmp2 = call i32 @strlen( i8* %P ) nounwind readonly ; <i32> [#uses=1]
+ %tmp3 = icmp eq i32 %tmp2, 100 ; <i1> [#uses=1]
+ %tmp34 = zext i1 %tmp3 to i8 ; <i8> [#uses=1]
+ %toBool = icmp ne i8 %tmp34, 0 ; <i1> [#uses=1]
+ br i1 %toBool, label %bb, label %bb6
+
+bb: ; preds = %entry
+ br label %bb27
+
+bb6: ; preds = %entry
+ %tmp8 = add i32 %g, 42 ; <i32> [#uses=2]
+ %tmp10 = call i32 @strlen( i8* %P ) nounwind readonly ; <i32> [#uses=1]
+ %tmp11 = icmp eq i32 %tmp10, 100 ; <i1> [#uses=1]
+ %tmp1112 = zext i1 %tmp11 to i8 ; <i8> [#uses=1]
+ %toBool13 = icmp ne i8 %tmp1112, 0 ; <i1> [#uses=1]
+ br i1 %toBool13, label %bb14, label %bb16
+
+bb14: ; preds = %bb6
+ br label %bb27
+
+bb16: ; preds = %bb6
+ %tmp18 = mul i32 %tmp8, 2 ; <i32> [#uses=1]
+ %tmp20 = call i32 @strlen( i8* %P ) nounwind readonly ; <i32> [#uses=1]
+ %tmp21 = icmp eq i32 %tmp20, 100 ; <i1> [#uses=1]
+ %tmp2122 = zext i1 %tmp21 to i8 ; <i8> [#uses=1]
+ %toBool23 = icmp ne i8 %tmp2122, 0 ; <i1> [#uses=1]
+ br i1 %toBool23, label %bb24, label %bb26
+
+bb24: ; preds = %bb16
+ br label %bb27
+
+bb26: ; preds = %bb16
+ br label %bb27
+
+bb27: ; preds = %bb26, %bb24, %bb14, %bb
+ %tmp.0 = phi i32 [ 11, %bb26 ], [ %tmp18, %bb24 ], [ %tmp8, %bb14 ], [ %g, %bb ] ; <i32> [#uses=1]
+ br label %return
+
+return: ; preds = %bb27
+ ret i32 %tmp.0
+}
+
+declare i32 @strlen(i8*) nounwind readonly
diff --git a/test/Transforms/GVN/calls-readonly.ll b/test/Transforms/GVN/calls-readonly.ll
new file mode 100644
index 0000000..97ec915
--- /dev/null
+++ b/test/Transforms/GVN/calls-readonly.ll
@@ -0,0 +1,29 @@
+; RUN: opt < %s -basicaa -gvn -S | grep {call.*strlen} | count 1
+; Should delete the second call to strlen even though the intervening strchr call exists.
+
+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"
+target triple = "i386-apple-darwin7"
+
+define i8* @test(i8* %P, i8* %Q, i32 %x, i32 %y) nounwind readonly {
+entry:
+ %0 = tail call i32 @strlen(i8* %P) ; <i32> [#uses=2]
+ %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
+ br i1 %1, label %bb, label %bb1
+
+bb: ; preds = %entry
+ %2 = sdiv i32 %x, %y ; <i32> [#uses=1]
+ br label %bb1
+
+bb1: ; preds = %bb, %entry
+ %x_addr.0 = phi i32 [ %2, %bb ], [ %x, %entry ] ; <i32> [#uses=1]
+ %3 = tail call i8* @strchr(i8* %Q, i32 97) ; <i8*> [#uses=1]
+ %4 = tail call i32 @strlen(i8* %P) ; <i32> [#uses=1]
+ %5 = add i32 %x_addr.0, %0 ; <i32> [#uses=1]
+ %.sum = sub i32 %5, %4 ; <i32> [#uses=1]
+ %6 = getelementptr i8* %3, i32 %.sum ; <i8*> [#uses=1]
+ ret i8* %6
+}
+
+declare i32 @strlen(i8*) nounwind readonly
+
+declare i8* @strchr(i8*, i32) nounwind readonly
diff --git a/test/Transforms/GVN/condprop.ll b/test/Transforms/GVN/condprop.ll
new file mode 100644
index 0000000..e212d79
--- /dev/null
+++ b/test/Transforms/GVN/condprop.ll
@@ -0,0 +1,52 @@
+; RUN: opt < %s -gvn -S | grep {br i1 false}
+
+@a = external global i32 ; <i32*> [#uses=7]
+
+define i32 @foo() nounwind {
+entry:
+ %0 = load i32* @a, align 4 ; <i32> [#uses=1]
+ %1 = icmp eq i32 %0, 4 ; <i1> [#uses=1]
+ br i1 %1, label %bb, label %bb1
+
+bb: ; preds = %entry
+ br label %bb8
+
+bb1: ; preds = %entry
+ %2 = load i32* @a, align 4 ; <i32> [#uses=1]
+ %3 = icmp eq i32 %2, 5 ; <i1> [#uses=1]
+ br i1 %3, label %bb2, label %bb3
+
+bb2: ; preds = %bb1
+ br label %bb8
+
+bb3: ; preds = %bb1
+ %4 = load i32* @a, align 4 ; <i32> [#uses=1]
+ %5 = icmp eq i32 %4, 4 ; <i1> [#uses=1]
+ br i1 %5, label %bb4, label %bb5
+
+bb4: ; preds = %bb3
+ %6 = load i32* @a, align 4 ; <i32> [#uses=1]
+ %7 = add i32 %6, 5 ; <i32> [#uses=1]
+ br label %bb8
+
+bb5: ; preds = %bb3
+ %8 = load i32* @a, align 4 ; <i32> [#uses=1]
+ %9 = icmp eq i32 %8, 5 ; <i1> [#uses=1]
+ br i1 %9, label %bb6, label %bb7
+
+bb6: ; preds = %bb5
+ %10 = load i32* @a, align 4 ; <i32> [#uses=1]
+ %11 = add i32 %10, 4 ; <i32> [#uses=1]
+ br label %bb8
+
+bb7: ; preds = %bb5
+ %12 = load i32* @a, align 4 ; <i32> [#uses=1]
+ br label %bb8
+
+bb8: ; preds = %bb7, %bb6, %bb4, %bb2, %bb
+ %.0 = phi i32 [ %12, %bb7 ], [ %11, %bb6 ], [ %7, %bb4 ], [ 4, %bb2 ], [ 5, %bb ] ; <i32> [#uses=1]
+ br label %return
+
+return: ; preds = %bb8
+ ret i32 %.0
+}
diff --git a/test/Transforms/GVN/crash-no-aa.ll b/test/Transforms/GVN/crash-no-aa.ll
new file mode 100644
index 0000000..dae65dd
--- /dev/null
+++ b/test/Transforms/GVN/crash-no-aa.ll
@@ -0,0 +1,16 @@
+; RUN: opt -no-aa -gvn -S %s
+
+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-v1
+28:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
+target triple = "x86_64-unknown-freebsd8.0"
+
+; PR5744
+define i32 @test1({i16, i32} *%P) {
+ %P2 = getelementptr {i16, i32} *%P, i32 0, i32 0
+ store i16 42, i16* %P2
+
+ %P3 = getelementptr {i16, i32} *%P, i32 0, i32 1
+ %V = load i32* %P3
+ ret i32 %V
+}
+
diff --git a/test/Transforms/GVN/crash.ll b/test/Transforms/GVN/crash.ll
new file mode 100644
index 0000000..9167b6e
--- /dev/null
+++ b/test/Transforms/GVN/crash.ll
@@ -0,0 +1,137 @@
+; RUN: opt -gvn %s -disable-output
+
+; PR5631
+
+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"
+target triple = "x86_64-apple-darwin10.0"
+
+define i32* @peel_to_type(i8* %name, i32 %namelen, i32* %o, i32 %expected_type) nounwind ssp {
+entry:
+ br i1 undef, label %if.end13, label %while.body.preheader
+
+
+if.end13: ; preds = %if.then6
+ br label %while.body.preheader
+
+while.body.preheader: ; preds = %if.end13, %if.end
+ br label %while.body
+
+while.body: ; preds = %while.body.backedge, %while.body.preheader
+ %o.addr.0 = phi i32* [ undef, %while.body.preheader ], [ %o.addr.0.be, %while.body.backedge ] ; <i32*> [#uses=2]
+ br i1 false, label %return.loopexit, label %lor.lhs.false
+
+lor.lhs.false: ; preds = %while.body
+ %tmp20 = bitcast i32* %o.addr.0 to i32* ; <i32*> [#uses=1]
+ %tmp22 = load i32* %tmp20 ; <i32> [#uses=0]
+ br i1 undef, label %land.lhs.true24, label %if.end31
+
+land.lhs.true24: ; preds = %lor.lhs.false
+ %call28 = call i32* @parse_object(i8* undef) nounwind ; <i32*> [#uses=0]
+ br i1 undef, label %return.loopexit, label %if.end31
+
+if.end31: ; preds = %land.lhs.true24, %lor.lhs.false
+ br i1 undef, label %return.loopexit, label %if.end41
+
+if.end41: ; preds = %if.end31
+ %tmp43 = bitcast i32* %o.addr.0 to i32* ; <i32*> [#uses=1]
+ %tmp45 = load i32* %tmp43 ; <i32> [#uses=0]
+ br i1 undef, label %if.then50, label %if.else
+
+if.then50: ; preds = %if.end41
+ %tmp53 = load i32** undef ; <i32*> [#uses=1]
+ br label %while.body.backedge
+
+if.else: ; preds = %if.end41
+ br i1 undef, label %if.then62, label %if.else67
+
+if.then62: ; preds = %if.else
+ br label %while.body.backedge
+
+while.body.backedge: ; preds = %if.then62, %if.then50
+ %o.addr.0.be = phi i32* [ %tmp53, %if.then50 ], [ undef, %if.then62 ] ; <i32*> [#uses=1]
+ br label %while.body
+
+if.else67: ; preds = %if.else
+ ret i32* null
+
+return.loopexit: ; preds = %if.end31, %land.lhs.true24, %while.body
+ ret i32* undef
+}
+
+declare i32* @parse_object(i8*)
+
+
+
+
+
+
+%struct.attribute_spec = type { i8*, i32, i32, i8, i8, i8 }
+
+@attribute_tables = external global [4 x %struct.attribute_spec*] ; <[4 x %struct.attribute_spec*]*> [#uses=2]
+
+define void @decl_attributes() nounwind {
+entry:
+ br label %bb69.i
+
+bb69.i: ; preds = %bb57.i.preheader
+ %tmp4 = getelementptr inbounds [4 x %struct.attribute_spec*]* @attribute_tables, i32 0, i32 undef ; <%struct.attribute_spec**> [#uses=1]
+ %tmp3 = load %struct.attribute_spec** %tmp4, align 4 ; <%struct.attribute_spec*> [#uses=1]
+ br label %bb65.i
+
+bb65.i: ; preds = %bb65.i.preheader, %bb64.i
+ %storemerge6.i = phi i32 [ 1, %bb64.i ], [ 0, %bb69.i ] ; <i32> [#uses=3]
+ %scevgep14 = getelementptr inbounds %struct.attribute_spec* %tmp3, i32 %storemerge6.i, i32 0 ; <i8**> [#uses=1]
+ %tmp2 = load i8** %scevgep14, align 4 ; <i8*> [#uses=0]
+ %tmp = load %struct.attribute_spec** %tmp4, align 4 ; <%struct.attribute_spec*> [#uses=1]
+ %scevgep1516 = getelementptr inbounds %struct.attribute_spec* %tmp, i32 %storemerge6.i, i32 0 ; <i8**> [#uses=0]
+ unreachable
+
+bb64.i: ; Unreachable
+ br label %bb65.i
+
+bb66.i: ; Unreachable
+ br label %bb69.i
+}
+
+
+
+; rdar://7438974
+
+@g = external global i64, align 8
+
+define i32* @foo() {
+do.end17.i:
+ %tmp18.i = load i7** undef
+ %tmp1 = bitcast i7* %tmp18.i to i8*
+ br i1 undef, label %do.body36.i, label %if.then21.i
+
+if.then21.i:
+ %tmp2 = bitcast i7* %tmp18.i to i8*
+ ret i32* undef
+
+do.body36.i:
+ %ivar38.i = load i64* @g
+ %tmp3 = bitcast i7* %tmp18.i to i8*
+ %add.ptr39.sum.i = add i64 %ivar38.i, 8
+ %tmp40.i = getelementptr inbounds i8* %tmp3, i64 %add.ptr39.sum.i
+ %tmp4 = bitcast i8* %tmp40.i to i64*
+ %tmp41.i = load i64* %tmp4
+ br i1 undef, label %if.then48.i, label %do.body57.i
+
+if.then48.i:
+ %call54.i = call i32 @foo2()
+ br label %do.body57.i
+
+do.body57.i:
+ %tmp58.i = load i7** undef
+ %ivar59.i = load i64* @g
+ %tmp5 = bitcast i7* %tmp58.i to i8*
+ %add.ptr65.sum.i = add i64 %ivar59.i, 8
+ %tmp66.i = getelementptr inbounds i8* %tmp5, i64 %add.ptr65.sum.i
+ %tmp6 = bitcast i8* %tmp66.i to i64*
+ %tmp67.i = load i64* %tmp6
+ ret i32* undef
+}
+
+declare i32 @foo2()
+
diff --git a/test/Transforms/GVN/dg.exp b/test/Transforms/GVN/dg.exp
new file mode 100644
index 0000000..f200589
--- /dev/null
+++ b/test/Transforms/GVN/dg.exp
@@ -0,0 +1,3 @@
+load_lib llvm.exp
+
+RunLLVMTests [lsort [glob -nocomplain $srcdir/$subdir/*.{ll,c,cpp}]]
diff --git a/test/Transforms/GVN/invariant-simple.ll b/test/Transforms/GVN/invariant-simple.ll
new file mode 100644
index 0000000..6de75f1
--- /dev/null
+++ b/test/Transforms/GVN/invariant-simple.ll
@@ -0,0 +1,36 @@
+; RUN: opt < %s -gvn -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"
+target triple = "i386-apple-darwin7"
+
+define i8 @test(i8* %P) nounwind {
+; CHECK: @test
+; CHECK-NOT: load
+; CHECK: ret i8
+entry:
+ store i8 1, i8* %P
+ %0 = call {}* @llvm.invariant.start(i64 32, i8* %P)
+ %1 = tail call i32 @foo(i8* %P)
+ call void @llvm.invariant.end({}* %0, i64 32, i8* %P)
+ %2 = load i8* %P
+ ret i8 %2
+}
+
+define i8 @test2(i8* %P) nounwind {
+; CHECK: @test2
+; CHECK: store i8 1
+; CHECK: store i8 2
+; CHECK: ret i8 0
+entry:
+ store i8 1, i8* %P
+ %0 = call {}* @llvm.invariant.start(i64 32, i8* %P)
+ %1 = tail call i32 @bar(i8* %P)
+ call void @llvm.invariant.end({}* %0, i64 32, i8* %P)
+ store i8 2, i8* %P
+ ret i8 0
+}
+
+declare i32 @foo(i8*) nounwind
+declare i32 @bar(i8*) nounwind readonly
+declare {}* @llvm.invariant.start(i64 %S, i8* nocapture %P) readonly
+declare void @llvm.invariant.end({}* %S, i64 %SS, i8* nocapture %P) \ No newline at end of file
diff --git a/test/Transforms/GVN/lifetime-simple.ll b/test/Transforms/GVN/lifetime-simple.ll
new file mode 100644
index 0000000..8139246
--- /dev/null
+++ b/test/Transforms/GVN/lifetime-simple.ll
@@ -0,0 +1,20 @@
+; RUN: opt < %s -gvn -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"
+target triple = "i386-apple-darwin7"
+
+define i8 @test(i8* %P) nounwind {
+; CHECK: lifetime.start
+; CHECK-NOT: load
+; CHECK: lifetime.end
+entry:
+ call void @llvm.lifetime.start(i64 32, i8* %P)
+ %0 = load i8* %P
+ store i8 1, i8* %P
+ call void @llvm.lifetime.end(i64 32, i8* %P)
+ %1 = load i8* %P
+ ret i8 %1
+}
+
+declare {}* @llvm.lifetime.start(i64 %S, i8* nocapture %P) readonly
+declare void @llvm.lifetime.end(i64 %S, i8* nocapture %P) \ No newline at end of file
diff --git a/test/Transforms/GVN/load-constant-mem.ll b/test/Transforms/GVN/load-constant-mem.ll
new file mode 100644
index 0000000..87f33ea
--- /dev/null
+++ b/test/Transforms/GVN/load-constant-mem.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -gvn -instcombine -S | grep {ret i32 0}
+; PR4189
+@G = external constant [4 x i32]
+
+define i32 @test(i8* %p, i32 %i) nounwind {
+entry:
+ %P = getelementptr [4 x i32]* @G, i32 0, i32 %i
+ %A = load i32* %P
+ store i8 4, i8* %p
+ %B = load i32* %P
+ %C = sub i32 %A, %B
+ ret i32 %C
+}
diff --git a/test/Transforms/GVN/load-pre-align.ll b/test/Transforms/GVN/load-pre-align.ll
new file mode 100644
index 0000000..3a66c0b
--- /dev/null
+++ b/test/Transforms/GVN/load-pre-align.ll
@@ -0,0 +1,44 @@
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+target datalayout = "e-p:32:32:32-i1:8:32-i8:8:32-i16:16:32-i32:32:32-i64:32:32-f32:32:32-f64:32:32-v64:64:64-v128:128:128-a0:0:32-n32"
+
+@p = external global i32
+
+define arm_apcscc i32 @test(i32 %n) nounwind {
+; CHECK: @test
+entry:
+ br label %for.cond
+
+; loads aligned greater than the memory should not be moved past conditionals
+; CHECK-NOT: load
+; CHECK: br i1
+
+for.cond:
+ %i.0 = phi i32 [ 0, %entry ], [ %indvar.next, %for.inc ]
+ %cmp = icmp slt i32 %i.0, %n
+ br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
+
+for.cond.for.end_crit_edge:
+; ...but PRE can still move the load out of for.end to here.
+; CHECK: for.cond.for.end_crit_edge:
+; CHECK-NEXT: load
+ br label %for.end
+
+for.body:
+ %tmp3 = load i32* @p, align 8
+ %dec = add i32 %tmp3, -1
+ store i32 %dec, i32* @p
+ %cmp6 = icmp slt i32 %dec, 0
+ br i1 %cmp6, label %for.body.for.end_crit_edge, label %for.inc
+
+for.body.for.end_crit_edge:
+ br label %for.end
+
+for.inc:
+ %indvar.next = add i32 %i.0, 1
+ br label %for.cond
+
+for.end:
+ %tmp9 = load i32* @p, align 8
+ ret i32 %tmp9
+}
diff --git a/test/Transforms/GVN/local-pre.ll b/test/Transforms/GVN/local-pre.ll
new file mode 100644
index 0000000..5f03984
--- /dev/null
+++ b/test/Transforms/GVN/local-pre.ll
@@ -0,0 +1,18 @@
+; RUN: opt < %s -gvn -enable-pre -S | grep {b.pre}
+
+define i32 @main(i32 %p) {
+block1:
+
+ br i1 true, label %block2, label %block3
+
+block2:
+ %a = add i32 %p, 1
+ br label %block4
+
+block3:
+ br label %block4
+
+block4:
+ %b = add i32 %p, 1
+ ret i32 %b
+}
diff --git a/test/Transforms/GVN/lpre-call-wrap-2.ll b/test/Transforms/GVN/lpre-call-wrap-2.ll
new file mode 100644
index 0000000..79512a3
--- /dev/null
+++ b/test/Transforms/GVN/lpre-call-wrap-2.ll
@@ -0,0 +1,40 @@
+; RUN: opt -S -gvn -enable-load-pre %s | FileCheck %s
+;
+; The partially redundant load in bb1 should be hoisted to "bb". This comes
+; from this C code (GCC PR 23455):
+; unsigned outcnt; extern void flush_outbuf(void);
+; void bi_windup(unsigned char *outbuf, unsigned char bi_buf) {
+; outbuf[outcnt] = bi_buf;
+; if (outcnt == 16384)
+; flush_outbuf();
+; outbuf[outcnt] = bi_buf;
+; }
+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"
+target triple = "i386-apple-darwin7"
+@outcnt = common global i32 0 ; <i32*> [#uses=3]
+
+define void @bi_windup(i8* %outbuf, i8 zeroext %bi_buf) nounwind {
+entry:
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ %0 = load i32* @outcnt, align 4 ; <i32> [#uses=1]
+ %1 = getelementptr i8* %outbuf, i32 %0 ; <i8*> [#uses=1]
+ store i8 %bi_buf, i8* %1, align 1
+ %2 = load i32* @outcnt, align 4 ; <i32> [#uses=1]
+ %3 = icmp eq i32 %2, 16384 ; <i1> [#uses=1]
+ br i1 %3, label %bb, label %bb1
+
+bb: ; preds = %entry
+ call void @flush_outbuf() nounwind
+ br label %bb1
+
+bb1: ; preds = %bb, %entry
+; CHECK: bb1:
+; CHECK-NEXT: phi
+; CHECK-NEXT: getelementptr
+ %4 = load i32* @outcnt, align 4 ; <i32> [#uses=1]
+ %5 = getelementptr i8* %outbuf, i32 %4 ; <i8*> [#uses=1]
+ store i8 %bi_buf, i8* %5, align 1
+ ret void
+}
+
+declare void @flush_outbuf()
diff --git a/test/Transforms/GVN/lpre-call-wrap.ll b/test/Transforms/GVN/lpre-call-wrap.ll
new file mode 100644
index 0000000..4046279
--- /dev/null
+++ b/test/Transforms/GVN/lpre-call-wrap.ll
@@ -0,0 +1,55 @@
+; RUN: opt -S -gvn -enable-load-pre %s | FileCheck %s
+;
+; Make sure the load in bb3.backedge is removed and moved into bb1 after the
+; call. This makes the non-call case faster.
+;
+; This test is derived from this C++ code (GCC PR 37810):
+; void g();
+; struct A {
+; int n; int m;
+; A& operator++(void) { ++n; if (n == m) g(); return *this; }
+; A() : n(0), m(0) { }
+; friend bool operator!=(A const& a1, A const& a2) { return a1.n != a2.n; }
+; };
+; void testfunction(A& iter) { A const end; while (iter != end) ++iter; }
+;
+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"
+target triple = "i386-apple-darwin7"
+ %struct.A = type { i32, i32 }
+
+define void @_Z12testfunctionR1A(%struct.A* %iter) {
+entry:
+ %0 = getelementptr %struct.A* %iter, i32 0, i32 0 ; <i32*> [#uses=3]
+ %1 = load i32* %0, align 4 ; <i32> [#uses=2]
+ %2 = icmp eq i32 %1, 0 ; <i1> [#uses=1]
+ br i1 %2, label %return, label %bb.nph
+
+bb.nph: ; preds = %entry
+ %3 = getelementptr %struct.A* %iter, i32 0, i32 1 ; <i32*> [#uses=1]
+ br label %bb
+
+bb: ; preds = %bb3.backedge, %bb.nph
+ %.rle = phi i32 [ %1, %bb.nph ], [ %7, %bb3.backedge ] ; <i32> [#uses=1]
+ %4 = add i32 %.rle, 1 ; <i32> [#uses=2]
+ store i32 %4, i32* %0, align 4
+ %5 = load i32* %3, align 4 ; <i32> [#uses=1]
+ %6 = icmp eq i32 %4, %5 ; <i1> [#uses=1]
+ br i1 %6, label %bb1, label %bb3.backedge
+
+bb1: ; preds = %bb
+ tail call void @_Z1gv()
+ br label %bb3.backedge
+
+bb3.backedge: ; preds = %bb, %bb1
+; CHECK: bb3.backedge:
+; CHECK-NEXT: phi
+; CHECK-NEXT: icmp
+ %7 = load i32* %0, align 4 ; <i32> [#uses=2]
+ %8 = icmp eq i32 %7, 0 ; <i1> [#uses=1]
+ br i1 %8, label %return, label %bb
+
+return: ; preds = %bb3.backedge, %entry
+ ret void
+}
+
+declare void @_Z1gv()
diff --git a/test/Transforms/GVN/mixed.ll b/test/Transforms/GVN/mixed.ll
new file mode 100644
index 0000000..5152f68
--- /dev/null
+++ b/test/Transforms/GVN/mixed.ll
@@ -0,0 +1,13 @@
+; RUN: opt < %s -gvn -S | not grep DEADLOAD
+; RUN: opt < %s -gvn -S | not grep DEADGEP
+
+define i32 @main(i32** %p) {
+block1:
+ %z1 = load i32** %p
+ %z2 = getelementptr i32* %z1, i32 0
+ %z3 = load i32* %z2
+ %DEADLOAD = load i32** %p
+ %DEADGEP = getelementptr i32* %DEADLOAD, i32 0
+ %DEADLOAD2 = load i32* %DEADGEP
+ ret i32 %DEADLOAD2
+}
diff --git a/test/Transforms/GVN/nonescaping-malloc.ll b/test/Transforms/GVN/nonescaping-malloc.ll
new file mode 100644
index 0000000..5a42d95
--- /dev/null
+++ b/test/Transforms/GVN/nonescaping-malloc.ll
@@ -0,0 +1,108 @@
+; RUN: opt < %s -gvn -stats -disable-output |& grep {Number of loads deleted}
+; rdar://7363102
+
+; GVN should be able to eliminate load %tmp22.i, because it is redundant with
+; load %tmp8.i. This requires being able to prove that %tmp7.i doesn't
+; alias the malloc'd value %tmp.i20.i.i, which it can do since %tmp7.i
+; is derived from %tmp5.i which is computed from a load, and %tmp.i20.i.i
+; is never stored and does not escape.
+
+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"
+target triple = "x86_64-apple-darwin10.0"
+
+%"struct.llvm::MallocAllocator" = type <{ i8 }>
+%"struct.llvm::StringMap<void*,llvm::MallocAllocator>" = type { %"struct.llvm::StringMapImpl", %"struct.llvm::MallocAllocator" }
+%"struct.llvm::StringMapEntry<void*>" = type { %"struct.llvm::StringMapEntryBase", i8* }
+%"struct.llvm::StringMapEntryBase" = type { i32 }
+%"struct.llvm::StringMapImpl" = type { %"struct.llvm::StringMapImpl::ItemBucket"*, i32, i32, i32, i32 }
+%"struct.llvm::StringMapImpl::ItemBucket" = type { i32, %"struct.llvm::StringMapEntryBase"* }
+%"struct.llvm::StringRef" = type { i8*, i64 }
+
+define %"struct.llvm::StringMapEntry<void*>"* @_Z3fooRN4llvm9StringMapIPvNS_15MallocAllocatorEEEPKc(%"struct.llvm::StringMap<void*,llvm::MallocAllocator>"* %X, i8* %P) ssp {
+entry:
+ %tmp = alloca %"struct.llvm::StringRef", align 8 ; <%"struct.llvm::StringRef"*> [#uses=3]
+ %tmp.i = getelementptr inbounds %"struct.llvm::StringRef"* %tmp, i64 0, i32 0 ; <i8**> [#uses=1]
+ store i8* %P, i8** %tmp.i, align 8
+ %tmp1.i = call i64 @strlen(i8* %P) nounwind readonly ; <i64> [#uses=1]
+ %tmp2.i = getelementptr inbounds %"struct.llvm::StringRef"* %tmp, i64 0, i32 1 ; <i64*> [#uses=1]
+ store i64 %tmp1.i, i64* %tmp2.i, align 8
+ %tmp1 = call %"struct.llvm::StringMapEntry<void*>"* @_ZN4llvm9StringMapIPvNS_15MallocAllocatorEE16GetOrCreateValueERKNS_9StringRefE(%"struct.llvm::StringMap<void*,llvm::MallocAllocator>"* %X, %"struct.llvm::StringRef"* %tmp) ssp ; <%"struct.llvm::StringMapEntry<void*>"*> [#uses=1]
+ ret %"struct.llvm::StringMapEntry<void*>"* %tmp1
+}
+
+declare i64 @strlen(i8* nocapture) nounwind readonly
+
+declare noalias i8* @malloc(i64) nounwind
+
+declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
+
+declare i32 @_ZN4llvm13StringMapImpl15LookupBucketForENS_9StringRefE(%"struct.llvm::StringMapImpl"*, i64, i64)
+
+define linkonce_odr %"struct.llvm::StringMapEntry<void*>"* @_ZN4llvm9StringMapIPvNS_15MallocAllocatorEE16GetOrCreateValueERKNS_9StringRefE(%"struct.llvm::StringMap<void*,llvm::MallocAllocator>"* %this, %"struct.llvm::StringRef"* nocapture %Key) ssp align 2 {
+entry:
+ %elt = bitcast %"struct.llvm::StringRef"* %Key to i64* ; <i64*> [#uses=1]
+ %val = load i64* %elt ; <i64> [#uses=3]
+ %tmp = getelementptr inbounds %"struct.llvm::StringRef"* %Key, i64 0, i32 1 ; <i64*> [#uses=1]
+ %val2 = load i64* %tmp ; <i64> [#uses=2]
+ %tmp2.i = getelementptr inbounds %"struct.llvm::StringMap<void*,llvm::MallocAllocator>"* %this, i64 0, i32 0 ; <%"struct.llvm::StringMapImpl"*> [#uses=1]
+ %tmp3.i = tail call i32 @_ZN4llvm13StringMapImpl15LookupBucketForENS_9StringRefE(%"struct.llvm::StringMapImpl"* %tmp2.i, i64 %val, i64 %val2) ; <i32> [#uses=1]
+ %tmp4.i = getelementptr inbounds %"struct.llvm::StringMap<void*,llvm::MallocAllocator>"* %this, i64 0, i32 0, i32 0 ; <%"struct.llvm::StringMapImpl::ItemBucket"**> [#uses=1]
+ %tmp5.i = load %"struct.llvm::StringMapImpl::ItemBucket"** %tmp4.i, align 8 ; <%"struct.llvm::StringMapImpl::ItemBucket"*> [#uses=1]
+ %tmp6.i = zext i32 %tmp3.i to i64 ; <i64> [#uses=1]
+ %tmp7.i = getelementptr inbounds %"struct.llvm::StringMapImpl::ItemBucket"* %tmp5.i, i64 %tmp6.i, i32 1 ; <%"struct.llvm::StringMapEntryBase"**> [#uses=2]
+ %tmp8.i = load %"struct.llvm::StringMapEntryBase"** %tmp7.i, align 8 ; <%"struct.llvm::StringMapEntryBase"*> [#uses=3]
+ %tmp9.i = icmp eq %"struct.llvm::StringMapEntryBase"* %tmp8.i, null ; <i1> [#uses=1]
+ %tmp13.i = icmp eq %"struct.llvm::StringMapEntryBase"* %tmp8.i, inttoptr (i64 -1 to %"struct.llvm::StringMapEntryBase"*) ; <i1> [#uses=1]
+ %or.cond.i = or i1 %tmp9.i, %tmp13.i ; <i1> [#uses=1]
+ br i1 %or.cond.i, label %bb4.i, label %bb6.i
+
+bb4.i: ; preds = %entry
+ %tmp41.i = inttoptr i64 %val to i8* ; <i8*> [#uses=2]
+ %tmp4.i35.i = getelementptr inbounds i8* %tmp41.i, i64 %val2 ; <i8*> [#uses=1]
+ %tmp.i.i = ptrtoint i8* %tmp4.i35.i to i64 ; <i64> [#uses=1]
+ %tmp1.i.i = trunc i64 %tmp.i.i to i32 ; <i32> [#uses=1]
+ %tmp3.i.i = trunc i64 %val to i32 ; <i32> [#uses=1]
+ %tmp4.i.i = sub i32 %tmp1.i.i, %tmp3.i.i ; <i32> [#uses=3]
+ %tmp5.i.i = add i32 %tmp4.i.i, 17 ; <i32> [#uses=1]
+ %tmp8.i.i = zext i32 %tmp5.i.i to i64 ; <i64> [#uses=1]
+ %tmp.i20.i.i = tail call noalias i8* @malloc(i64 %tmp8.i.i) nounwind ; <i8*> [#uses=7]
+ %tmp10.i.i = bitcast i8* %tmp.i20.i.i to %"struct.llvm::StringMapEntry<void*>"* ; <%"struct.llvm::StringMapEntry<void*>"*> [#uses=2]
+ %tmp12.i.i = icmp eq i8* %tmp.i20.i.i, null ; <i1> [#uses=1]
+ br i1 %tmp12.i.i, label %_ZN4llvm14StringMapEntryIPvE6CreateINS_15MallocAllocatorES1_EEPS2_PKcS7_RT_T0_.exit.i, label %bb.i.i
+
+bb.i.i: ; preds = %bb4.i
+ %tmp.i.i.i.i = bitcast i8* %tmp.i20.i.i to i32* ; <i32*> [#uses=1]
+ store i32 %tmp4.i.i, i32* %tmp.i.i.i.i, align 4
+ %tmp1.i19.i.i = getelementptr inbounds i8* %tmp.i20.i.i, i64 8 ; <i8*> [#uses=1]
+ %0 = bitcast i8* %tmp1.i19.i.i to i8** ; <i8**> [#uses=1]
+ store i8* null, i8** %0, align 8
+ br label %_ZN4llvm14StringMapEntryIPvE6CreateINS_15MallocAllocatorES1_EEPS2_PKcS7_RT_T0_.exit.i
+
+_ZN4llvm14StringMapEntryIPvE6CreateINS_15MallocAllocatorES1_EEPS2_PKcS7_RT_T0_.exit.i: ; preds = %bb4.i, %bb.i.i
+ %tmp.i18.i.i = getelementptr inbounds i8* %tmp.i20.i.i, i64 16 ; <i8*> [#uses=1]
+ %tmp15.i.i = zext i32 %tmp4.i.i to i64 ; <i64> [#uses=2]
+ tail call void @llvm.memcpy.i64(i8* %tmp.i18.i.i, i8* %tmp41.i, i64 %tmp15.i.i, i32 1) nounwind
+ %tmp.i18.sum.i.i = add i64 %tmp15.i.i, 16 ; <i64> [#uses=1]
+ %tmp17.i.i = getelementptr inbounds i8* %tmp.i20.i.i, i64 %tmp.i18.sum.i.i ; <i8*> [#uses=1]
+ store i8 0, i8* %tmp17.i.i, align 1
+ %tmp.i.i.i = getelementptr inbounds i8* %tmp.i20.i.i, i64 8 ; <i8*> [#uses=1]
+ %1 = bitcast i8* %tmp.i.i.i to i8** ; <i8**> [#uses=1]
+ store i8* null, i8** %1, align 8
+ %tmp22.i = load %"struct.llvm::StringMapEntryBase"** %tmp7.i, align 8 ; <%"struct.llvm::StringMapEntryBase"*> [#uses=1]
+ %tmp24.i = icmp eq %"struct.llvm::StringMapEntryBase"* %tmp22.i, inttoptr (i64 -1 to %"struct.llvm::StringMapEntryBase"*) ; <i1> [#uses=1]
+ br i1 %tmp24.i, label %bb9.i, label %_ZN4llvm9StringMapIPvNS_15MallocAllocatorEE16GetOrCreateValueIS1_EERNS_14StringMapEntryIS1_EENS_9StringRefET_.exit
+
+bb6.i: ; preds = %entry
+ %tmp16.i = bitcast %"struct.llvm::StringMapEntryBase"* %tmp8.i to %"struct.llvm::StringMapEntry<void*>"* ; <%"struct.llvm::StringMapEntry<void*>"*> [#uses=1]
+ ret %"struct.llvm::StringMapEntry<void*>"* %tmp16.i
+
+bb9.i: ; preds = %_ZN4llvm14StringMapEntryIPvE6CreateINS_15MallocAllocatorES1_EEPS2_PKcS7_RT_T0_.exit.i
+ %tmp25.i = getelementptr inbounds %"struct.llvm::StringMap<void*,llvm::MallocAllocator>"* %this, i64 0, i32 0, i32 3 ; <i32*> [#uses=2]
+ %tmp26.i = load i32* %tmp25.i, align 8 ; <i32> [#uses=1]
+ %tmp27.i = add i32 %tmp26.i, -1 ; <i32> [#uses=1]
+ store i32 %tmp27.i, i32* %tmp25.i, align 8
+ ret %"struct.llvm::StringMapEntry<void*>"* %tmp10.i.i
+
+_ZN4llvm9StringMapIPvNS_15MallocAllocatorEE16GetOrCreateValueIS1_EERNS_14StringMapEntryIS1_EENS_9StringRefET_.exit: ; preds = %_ZN4llvm14StringMapEntryIPvE6CreateINS_15MallocAllocatorES1_EEPS2_PKcS7_RT_T0_.exit.i
+ ret %"struct.llvm::StringMapEntry<void*>"* %tmp10.i.i
+}
diff --git a/test/Transforms/GVN/null-aliases-nothing.ll b/test/Transforms/GVN/null-aliases-nothing.ll
new file mode 100644
index 0000000..4d533bb
--- /dev/null
+++ b/test/Transforms/GVN/null-aliases-nothing.ll
@@ -0,0 +1,20 @@
+; RUN: opt %s -gvn -S | FileCheck %s
+
+%t = type { i32 }
+declare void @test1f(i8*)
+
+define void @test1(%t* noalias %stuff ) {
+ %p = getelementptr inbounds %t* %stuff, i32 0, i32 0
+ %before = load i32* %p
+
+ call void @test1f(i8* null)
+
+ %after = load i32* %p ; <--- This should be a dead load
+ %sum = add i32 %before, %after
+
+ store i32 %sum, i32* %p
+ ret void
+; CHECK: load
+; CHECK-NOT: load
+; CHECK: ret void
+}
diff --git a/test/Transforms/GVN/pre-basic-add.ll b/test/Transforms/GVN/pre-basic-add.ll
new file mode 100644
index 0000000..c13099f
--- /dev/null
+++ b/test/Transforms/GVN/pre-basic-add.ll
@@ -0,0 +1,27 @@
+; RUN: opt < %s -gvn -enable-pre -S | grep {.pre}
+
+@H = common global i32 0 ; <i32*> [#uses=2]
+@G = common global i32 0 ; <i32*> [#uses=1]
+
+define i32 @test() nounwind {
+entry:
+ %0 = load i32* @H, align 4 ; <i32> [#uses=2]
+ %1 = call i32 (...)* @foo() nounwind ; <i32> [#uses=1]
+ %2 = icmp ne i32 %1, 0 ; <i1> [#uses=1]
+ br i1 %2, label %bb, label %bb1
+
+bb: ; preds = %entry
+ %3 = add i32 %0, 42 ; <i32> [#uses=1]
+ store i32 %3, i32* @G, align 4
+ br label %bb1
+
+bb1: ; preds = %bb, %entry
+ %4 = add i32 %0, 42 ; <i32> [#uses=1]
+ store i32 %4, i32* @H, align 4
+ br label %return
+
+return: ; preds = %bb1
+ ret i32 0
+}
+
+declare i32 @foo(...)
diff --git a/test/Transforms/GVN/pre-load.ll b/test/Transforms/GVN/pre-load.ll
new file mode 100644
index 0000000..7047d4e
--- /dev/null
+++ b/test/Transforms/GVN/pre-load.ll
@@ -0,0 +1,364 @@
+; RUN: opt < %s -gvn -enable-load-pre -S | FileCheck %s
+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"
+
+define i32 @test1(i32* %p, i1 %C) {
+; CHECK: @test1
+block1:
+ br i1 %C, label %block2, label %block3
+
+block2:
+ br label %block4
+; CHECK: block2:
+; CHECK-NEXT: load i32* %p
+
+block3:
+ store i32 0, i32* %p
+ br label %block4
+
+block4:
+ %PRE = load i32* %p
+ ret i32 %PRE
+; CHECK: block4:
+; CHECK-NEXT: phi i32
+; CHECK-NEXT: ret i32
+}
+
+; This is a simple phi translation case.
+define i32 @test2(i32* %p, i32* %q, i1 %C) {
+; CHECK: @test2
+block1:
+ br i1 %C, label %block2, label %block3
+
+block2:
+ br label %block4
+; CHECK: block2:
+; CHECK-NEXT: load i32* %q
+
+block3:
+ store i32 0, i32* %p
+ br label %block4
+
+block4:
+ %P2 = phi i32* [%p, %block3], [%q, %block2]
+ %PRE = load i32* %P2
+ ret i32 %PRE
+; CHECK: block4:
+; CHECK-NEXT: phi i32 [
+; CHECK-NOT: load
+; CHECK: ret i32
+}
+
+; This is a PRE case that requires phi translation through a GEP.
+define i32 @test3(i32* %p, i32* %q, i32** %Hack, i1 %C) {
+; CHECK: @test3
+block1:
+ %B = getelementptr i32* %q, i32 1
+ store i32* %B, i32** %Hack
+ br i1 %C, label %block2, label %block3
+
+block2:
+ br label %block4
+; CHECK: block2:
+; CHECK-NEXT: load i32* %B
+
+block3:
+ %A = getelementptr i32* %p, i32 1
+ store i32 0, i32* %A
+ br label %block4
+
+block4:
+ %P2 = phi i32* [%p, %block3], [%q, %block2]
+ %P3 = getelementptr i32* %P2, i32 1
+ %PRE = load i32* %P3
+ ret i32 %PRE
+; CHECK: block4:
+; CHECK-NEXT: phi i32 [
+; CHECK-NOT: load
+; CHECK: ret i32
+}
+
+;; Here the loaded address is available, but the computation is in 'block3'
+;; which does not dominate 'block2'.
+define i32 @test4(i32* %p, i32* %q, i32** %Hack, i1 %C) {
+; CHECK: @test4
+block1:
+ br i1 %C, label %block2, label %block3
+
+block2:
+ br label %block4
+; CHECK: block2:
+; CHECK: load i32*
+; CHECK: br label %block4
+
+block3:
+ %B = getelementptr i32* %q, i32 1
+ store i32* %B, i32** %Hack
+
+ %A = getelementptr i32* %p, i32 1
+ store i32 0, i32* %A
+ br label %block4
+
+block4:
+ %P2 = phi i32* [%p, %block3], [%q, %block2]
+ %P3 = getelementptr i32* %P2, i32 1
+ %PRE = load i32* %P3
+ ret i32 %PRE
+; CHECK: block4:
+; CHECK-NEXT: phi i32 [
+; CHECK-NOT: load
+; CHECK: ret i32
+}
+
+;void test5(int N, double *G) {
+; int j;
+; for (j = 0; j < N - 1; j++)
+; G[j] = G[j] + G[j+1];
+;}
+
+define void @test5(i32 %N, double* nocapture %G) nounwind ssp {
+; CHECK: @test5
+entry:
+ %0 = add i32 %N, -1
+ %1 = icmp sgt i32 %0, 0
+ br i1 %1, label %bb.nph, label %return
+
+bb.nph:
+ %tmp = zext i32 %0 to i64
+ br label %bb
+
+; CHECK: bb.nph:
+; CHECK: load double*
+; CHECK: br label %bb
+
+bb:
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp6, %bb ]
+ %tmp6 = add i64 %indvar, 1
+ %scevgep = getelementptr double* %G, i64 %tmp6
+ %scevgep7 = getelementptr double* %G, i64 %indvar
+ %2 = load double* %scevgep7, align 8
+ %3 = load double* %scevgep, align 8
+ %4 = fadd double %2, %3
+ store double %4, double* %scevgep7, align 8
+ %exitcond = icmp eq i64 %tmp6, %tmp
+ br i1 %exitcond, label %return, label %bb
+
+; Should only be one load in the loop.
+; CHECK: bb:
+; CHECK: load double*
+; CHECK-NOT: load double*
+; CHECK: br i1 %exitcond
+
+return:
+ ret void
+}
+
+;void test6(int N, double *G) {
+; int j;
+; for (j = 0; j < N - 1; j++)
+; G[j+1] = G[j] + G[j+1];
+;}
+
+define void @test6(i32 %N, double* nocapture %G) nounwind ssp {
+; CHECK: @test6
+entry:
+ %0 = add i32 %N, -1
+ %1 = icmp sgt i32 %0, 0
+ br i1 %1, label %bb.nph, label %return
+
+bb.nph:
+ %tmp = zext i32 %0 to i64
+ br label %bb
+
+; CHECK: bb.nph:
+; CHECK: load double*
+; CHECK: br label %bb
+
+bb:
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp6, %bb ]
+ %tmp6 = add i64 %indvar, 1
+ %scevgep = getelementptr double* %G, i64 %tmp6
+ %scevgep7 = getelementptr double* %G, i64 %indvar
+ %2 = load double* %scevgep7, align 8
+ %3 = load double* %scevgep, align 8
+ %4 = fadd double %2, %3
+ store double %4, double* %scevgep, align 8
+ %exitcond = icmp eq i64 %tmp6, %tmp
+ br i1 %exitcond, label %return, label %bb
+
+; Should only be one load in the loop.
+; CHECK: bb:
+; CHECK: load double*
+; CHECK-NOT: load double*
+; CHECK: br i1 %exitcond
+
+return:
+ ret void
+}
+
+;void test7(int N, double* G) {
+; long j;
+; G[1] = 1;
+; for (j = 1; j < N - 1; j++)
+; G[j+1] = G[j] + G[j+1];
+;}
+
+; This requires phi translation of the adds.
+define void @test7(i32 %N, double* nocapture %G) nounwind ssp {
+entry:
+ %0 = getelementptr inbounds double* %G, i64 1
+ store double 1.000000e+00, double* %0, align 8
+ %1 = add i32 %N, -1
+ %2 = icmp sgt i32 %1, 1
+ br i1 %2, label %bb.nph, label %return
+
+bb.nph:
+ %tmp = sext i32 %1 to i64
+ %tmp7 = add i64 %tmp, -1
+ br label %bb
+
+bb:
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp9, %bb ]
+ %tmp8 = add i64 %indvar, 2
+ %scevgep = getelementptr double* %G, i64 %tmp8
+ %tmp9 = add i64 %indvar, 1
+ %scevgep10 = getelementptr double* %G, i64 %tmp9
+ %3 = load double* %scevgep10, align 8
+ %4 = load double* %scevgep, align 8
+ %5 = fadd double %3, %4
+ store double %5, double* %scevgep, align 8
+ %exitcond = icmp eq i64 %tmp9, %tmp7
+ br i1 %exitcond, label %return, label %bb
+
+; Should only be one load in the loop.
+; CHECK: bb:
+; CHECK: load double*
+; CHECK-NOT: load double*
+; CHECK: br i1 %exitcond
+
+return:
+ ret void
+}
+
+;; Here the loaded address isn't available in 'block2' at all, requiring a new
+;; GEP to be inserted into it.
+define i32 @test8(i32* %p, i32* %q, i32** %Hack, i1 %C) {
+; CHECK: @test8
+block1:
+ br i1 %C, label %block2, label %block3
+
+block2:
+ br label %block4
+; CHECK: block2:
+; CHECK: load i32*
+; CHECK: br label %block4
+
+block3:
+ %A = getelementptr i32* %p, i32 1
+ store i32 0, i32* %A
+ br label %block4
+
+block4:
+ %P2 = phi i32* [%p, %block3], [%q, %block2]
+ %P3 = getelementptr i32* %P2, i32 1
+ %PRE = load i32* %P3
+ ret i32 %PRE
+; CHECK: block4:
+; CHECK-NEXT: phi i32 [
+; CHECK-NOT: load
+; CHECK: ret i32
+}
+
+;void test9(int N, double* G) {
+; long j;
+; for (j = 1; j < N - 1; j++)
+; G[j+1] = G[j] + G[j+1];
+;}
+
+; This requires phi translation of the adds.
+define void @test9(i32 %N, double* nocapture %G) nounwind ssp {
+entry:
+ add i32 0, 0
+ %1 = add i32 %N, -1
+ %2 = icmp sgt i32 %1, 1
+ br i1 %2, label %bb.nph, label %return
+
+bb.nph:
+ %tmp = sext i32 %1 to i64
+ %tmp7 = add i64 %tmp, -1
+ br label %bb
+
+; CHECK: bb.nph:
+; CHECK: load double*
+; CHECK: br label %bb
+
+bb:
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp9, %bb ]
+ %tmp8 = add i64 %indvar, 2
+ %scevgep = getelementptr double* %G, i64 %tmp8
+ %tmp9 = add i64 %indvar, 1
+ %scevgep10 = getelementptr double* %G, i64 %tmp9
+ %3 = load double* %scevgep10, align 8
+ %4 = load double* %scevgep, align 8
+ %5 = fadd double %3, %4
+ store double %5, double* %scevgep, align 8
+ %exitcond = icmp eq i64 %tmp9, %tmp7
+ br i1 %exitcond, label %return, label %bb
+
+; Should only be one load in the loop.
+; CHECK: bb:
+; CHECK: load double*
+; CHECK-NOT: load double*
+; CHECK: br i1 %exitcond
+
+return:
+ ret void
+}
+
+;void test10(int N, double* G) {
+; long j;
+; for (j = 1; j < N - 1; j++)
+; G[j] = G[j] + G[j+1] + G[j-1];
+;}
+
+; PR5501
+define void @test10(i32 %N, double* nocapture %G) nounwind ssp {
+entry:
+ %0 = add i32 %N, -1
+ %1 = icmp sgt i32 %0, 1
+ br i1 %1, label %bb.nph, label %return
+
+bb.nph:
+ %tmp = sext i32 %0 to i64
+ %tmp8 = add i64 %tmp, -1
+ br label %bb
+; CHECK: bb.nph:
+; CHECK: load double*
+; CHECK: load double*
+; CHECK: br label %bb
+
+
+bb:
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp11, %bb ]
+ %scevgep = getelementptr double* %G, i64 %indvar
+ %tmp9 = add i64 %indvar, 2
+ %scevgep10 = getelementptr double* %G, i64 %tmp9
+ %tmp11 = add i64 %indvar, 1
+ %scevgep12 = getelementptr double* %G, i64 %tmp11
+ %2 = load double* %scevgep12, align 8
+ %3 = load double* %scevgep10, align 8
+ %4 = fadd double %2, %3
+ %5 = load double* %scevgep, align 8
+ %6 = fadd double %4, %5
+ store double %6, double* %scevgep12, align 8
+ %exitcond = icmp eq i64 %tmp11, %tmp8
+ br i1 %exitcond, label %return, label %bb
+
+; Should only be one load in the loop.
+; CHECK: bb:
+; CHECK: load double*
+; CHECK-NOT: load double*
+; CHECK: br i1 %exitcond
+
+return:
+ ret void
+}
diff --git a/test/Transforms/GVN/pre-single-pred.ll b/test/Transforms/GVN/pre-single-pred.ll
new file mode 100644
index 0000000..706a16b
--- /dev/null
+++ b/test/Transforms/GVN/pre-single-pred.ll
@@ -0,0 +1,33 @@
+; RUN: opt < %s -gvn -enable-load-pre -S | not grep {tmp3 = load}
+
+@p = external global i32
+define i32 @f(i32 %n) nounwind {
+entry:
+ br label %for.cond
+
+for.cond: ; preds = %for.inc, %entry
+ %i.0 = phi i32 [ 0, %entry ], [ %indvar.next, %for.inc ] ; <i32> [#uses=2]
+ %cmp = icmp slt i32 %i.0, %n ; <i1> [#uses=1]
+ br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
+
+for.cond.for.end_crit_edge: ; preds = %for.cond
+ br label %for.end
+
+for.body: ; preds = %for.cond
+ %tmp3 = load i32* @p ; <i32> [#uses=1]
+ %dec = add i32 %tmp3, -1 ; <i32> [#uses=2]
+ store i32 %dec, i32* @p
+ %cmp6 = icmp slt i32 %dec, 0 ; <i1> [#uses=1]
+ br i1 %cmp6, label %for.body.for.end_crit_edge, label %for.inc
+
+for.body.for.end_crit_edge: ; preds = %for.body
+ br label %for.end
+
+for.inc: ; preds = %for.body
+ %indvar.next = add i32 %i.0, 1 ; <i32> [#uses=1]
+ br label %for.cond
+
+for.end: ; preds = %for.body.for.end_crit_edge, %for.cond.for.end_crit_edge
+ %tmp9 = load i32* @p ; <i32> [#uses=1]
+ ret i32 %tmp9
+}
diff --git a/test/Transforms/GVN/rle-must-alias.ll b/test/Transforms/GVN/rle-must-alias.ll
new file mode 100644
index 0000000..d61eb81
--- /dev/null
+++ b/test/Transforms/GVN/rle-must-alias.ll
@@ -0,0 +1,46 @@
+; RUN: opt < %s -gvn -S | grep {DEAD = phi i32 }
+
+; GVN should eliminate the fully redundant %9 GEP which
+; allows DEAD to be removed. This is PR3198.
+
+; The %7 and %4 loads combine to make %DEAD unneeded.
+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"
+target triple = "i386-apple-darwin7"
+@H = common global [100 x i32] zeroinitializer, align 32 ; <[100 x i32]*> [#uses=3]
+@G = common global i32 0 ; <i32*> [#uses=2]
+
+define i32 @test(i32 %i) nounwind {
+entry:
+ %0 = tail call i32 (...)* @foo() nounwind ; <i32> [#uses=1]
+ %1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
+ br i1 %1, label %bb1, label %bb
+
+bb: ; preds = %entry
+ %2 = tail call i32 (...)* @bar() nounwind ; <i32> [#uses=0]
+ %3 = getelementptr [100 x i32]* @H, i32 0, i32 %i ; <i32*> [#uses=1]
+ %4 = load i32* %3, align 4 ; <i32> [#uses=1]
+ store i32 %4, i32* @G, align 4
+ br label %bb3
+
+bb1: ; preds = %entry
+ %5 = tail call i32 (...)* @baz() nounwind ; <i32> [#uses=0]
+ %6 = getelementptr [100 x i32]* @H, i32 0, i32 %i ; <i32*> [#uses=1]
+ %7 = load i32* %6, align 4 ; <i32> [#uses=2]
+ store i32 %7, i32* @G, align 4
+ %8 = icmp eq i32 %7, 0 ; <i1> [#uses=1]
+ br i1 %8, label %bb3, label %bb4
+
+bb3: ; preds = %bb1, %bb
+ %9 = getelementptr [100 x i32]* @H, i32 0, i32 %i ; <i32*> [#uses=1]
+ %DEAD = load i32* %9, align 4 ; <i32> [#uses=1]
+ ret i32 %DEAD
+
+bb4: ; preds = %bb1
+ ret i32 0
+}
+
+declare i32 @foo(...)
+
+declare i32 @bar(...)
+
+declare i32 @baz(...)
diff --git a/test/Transforms/GVN/rle-no-phi-translate.ll b/test/Transforms/GVN/rle-no-phi-translate.ll
new file mode 100644
index 0000000..96dbf48
--- /dev/null
+++ b/test/Transforms/GVN/rle-no-phi-translate.ll
@@ -0,0 +1,28 @@
+; RUN: opt < %s -gvn -S | FileCheck %s
+; XFAIL: *
+; FIXME: This should be promotable, but memdep/gvn don't track values
+; path/edge sensitively enough.
+
+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"
+target triple = "i386-apple-darwin7"
+
+define i32 @g(i32* %b, i32* %c) nounwind {
+entry:
+ store i32 1, i32* %b
+ store i32 2, i32* %c
+
+ %t1 = icmp eq i32* %b, null ; <i1> [#uses=1]
+ br i1 %t1, label %bb, label %bb2
+
+bb: ; preds = %entry
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %c_addr.0 = phi i32* [ %b, %entry ], [ %c, %bb ] ; <i32*> [#uses=1]
+ %cv = load i32* %c_addr.0, align 4 ; <i32> [#uses=1]
+ ret i32 %cv
+; CHECK: bb2:
+; CHECK-NOT: load i32
+; CHECK: ret i32
+}
+
diff --git a/test/Transforms/GVN/rle-nonlocal.ll b/test/Transforms/GVN/rle-nonlocal.ll
new file mode 100644
index 0000000..5c73dad
--- /dev/null
+++ b/test/Transforms/GVN/rle-nonlocal.ll
@@ -0,0 +1,24 @@
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+define i32 @main(i32** %p) {
+block1:
+ br i1 true, label %block2, label %block3
+
+block2:
+ %a = load i32** %p
+ br label %block4
+
+block3:
+ %b = load i32** %p
+ br label %block4
+
+block4:
+; CHECK-NOT: %existingPHI = phi
+; CHECK: %DEAD = phi
+ %existingPHI = phi i32* [ %a, %block2 ], [ %b, %block3 ]
+ %DEAD = load i32** %p
+ %c = load i32* %DEAD
+ %d = load i32* %existingPHI
+ %e = add i32 %c, %d
+ ret i32 %e
+}
diff --git a/test/Transforms/GVN/rle-phi-translate.ll b/test/Transforms/GVN/rle-phi-translate.ll
new file mode 100644
index 0000000..6731f43
--- /dev/null
+++ b/test/Transforms/GVN/rle-phi-translate.ll
@@ -0,0 +1,146 @@
+; RUN: opt < %s -gvn -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"
+target triple = "i386-apple-darwin7"
+
+define i32 @test1(i32* %b, i32* %c) nounwind {
+; CHECK: @test1
+entry:
+ %g = alloca i32
+ %t1 = icmp eq i32* %b, null
+ br i1 %t1, label %bb, label %bb1
+
+bb:
+ %t2 = load i32* %c, align 4
+ %t3 = add i32 %t2, 1
+ store i32 %t3, i32* %g, align 4
+ br label %bb2
+
+bb1: ; preds = %entry
+ %t5 = load i32* %b, align 4
+ %t6 = add i32 %t5, 1
+ store i32 %t6, i32* %g, align 4
+ br label %bb2
+
+bb2: ; preds = %bb1, %bb
+ %c_addr.0 = phi i32* [ %g, %bb1 ], [ %c, %bb ]
+ %b_addr.0 = phi i32* [ %b, %bb1 ], [ %g, %bb ]
+ %cv = load i32* %c_addr.0, align 4
+ %bv = load i32* %b_addr.0, align 4
+; CHECK: %bv = phi i32
+; CHECK: %cv = phi i32
+; CHECK-NOT: load
+; CHECK: ret i32
+ %ret = add i32 %cv, %bv
+ ret i32 %ret
+}
+
+define i8 @test2(i1 %cond, i32* %b, i32* %c) nounwind {
+; CHECK: @test2
+entry:
+ br i1 %cond, label %bb, label %bb1
+
+bb:
+ %b1 = bitcast i32* %b to i8*
+ store i8 4, i8* %b1
+ br label %bb2
+
+bb1:
+ %c1 = bitcast i32* %c to i8*
+ store i8 92, i8* %c1
+ br label %bb2
+
+bb2:
+ %d = phi i32* [ %c, %bb1 ], [ %b, %bb ]
+ %d1 = bitcast i32* %d to i8*
+ %dv = load i8* %d1
+; CHECK: %dv = phi i8 [ 92, %bb1 ], [ 4, %bb ]
+; CHECK-NOT: load
+; CHECK: ret i8 %dv
+ ret i8 %dv
+}
+
+define i32 @test3(i1 %cond, i32* %b, i32* %c) nounwind {
+; CHECK: @test3
+entry:
+ br i1 %cond, label %bb, label %bb1
+
+bb:
+ %b1 = getelementptr i32* %b, i32 17
+ store i32 4, i32* %b1
+ br label %bb2
+
+bb1:
+ %c1 = getelementptr i32* %c, i32 7
+ store i32 82, i32* %c1
+ br label %bb2
+
+bb2:
+ %d = phi i32* [ %c, %bb1 ], [ %b, %bb ]
+ %i = phi i32 [ 7, %bb1 ], [ 17, %bb ]
+ %d1 = getelementptr i32* %d, i32 %i
+ %dv = load i32* %d1
+; CHECK: %dv = phi i32 [ 82, %bb1 ], [ 4, %bb ]
+; CHECK-NOT: load
+; CHECK: ret i32 %dv
+ ret i32 %dv
+}
+
+; PR5313
+define i32 @test4(i1 %cond, i32* %b, i32* %c) nounwind {
+; CHECK: @test4
+entry:
+ br i1 %cond, label %bb, label %bb1
+
+bb:
+ store i32 4, i32* %b
+ br label %bb2
+
+bb1:
+ %c1 = getelementptr i32* %c, i32 7
+ store i32 82, i32* %c1
+ br label %bb2
+
+bb2:
+ %d = phi i32* [ %c, %bb1 ], [ %b, %bb ]
+ %i = phi i32 [ 7, %bb1 ], [ 0, %bb ]
+ %d1 = getelementptr i32* %d, i32 %i
+ %dv = load i32* %d1
+; CHECK: %dv = phi i32 [ 82, %bb1 ], [ 4, %bb ]
+; CHECK-NOT: load
+; CHECK: ret i32 %dv
+ ret i32 %dv
+}
+
+
+
+; void test5(int N, double* G) {
+; for (long j = 1; j < 1000; j++)
+; G[j] = G[j] + G[j-1];
+; }
+;
+; Should compile into one load in the loop.
+define void @test5(i32 %N, double* nocapture %G) nounwind ssp {
+; CHECK: @test5
+bb.nph:
+ br label %for.body
+
+for.body:
+ %indvar = phi i64 [ 0, %bb.nph ], [ %tmp, %for.body ]
+ %arrayidx6 = getelementptr double* %G, i64 %indvar
+ %tmp = add i64 %indvar, 1
+ %arrayidx = getelementptr double* %G, i64 %tmp
+ %tmp3 = load double* %arrayidx
+ %tmp7 = load double* %arrayidx6
+ %add = fadd double %tmp3, %tmp7
+ store double %add, double* %arrayidx
+ %exitcond = icmp eq i64 %tmp, 999
+ br i1 %exitcond, label %for.end, label %for.body
+; CHECK: for.body:
+; CHECK: phi double
+; CHECK: load double
+; CHECK-NOT: load double
+; CHECK: br i1
+for.end:
+ ret void
+}
diff --git a/test/Transforms/GVN/rle-semidominated.ll b/test/Transforms/GVN/rle-semidominated.ll
new file mode 100644
index 0000000..04e8c38
--- /dev/null
+++ b/test/Transforms/GVN/rle-semidominated.ll
@@ -0,0 +1,19 @@
+; RUN: opt < %s -gvn -S | grep {DEAD = phi i32 }
+
+define i32 @main(i32* %p) {
+block1:
+ %z = load i32* %p
+ br i1 true, label %block2, label %block3
+
+block2:
+ br label %block4
+
+block3:
+ %b = bitcast i32 0 to i32
+ store i32 %b, i32* %p
+ br label %block4
+
+block4:
+ %DEAD = load i32* %p
+ ret i32 %DEAD
+}
diff --git a/test/Transforms/GVN/rle.ll b/test/Transforms/GVN/rle.ll
new file mode 100644
index 0000000..d419fd2
--- /dev/null
+++ b/test/Transforms/GVN/rle.ll
@@ -0,0 +1,534 @@
+; RUN: opt < %s -gvn -S | FileCheck %s
+
+; 32-bit little endian target.
+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"
+
+;; Trivial RLE test.
+define i32 @test0(i32 %V, i32* %P) {
+ store i32 %V, i32* %P
+
+ %A = load i32* %P
+ ret i32 %A
+; CHECK: @test0
+; CHECK: ret i32 %V
+}
+
+
+;;===----------------------------------------------------------------------===;;
+;; Tests for crashers
+;;===----------------------------------------------------------------------===;;
+
+;; PR5016
+define i8 @crash0({i32, i32} %A, {i32, i32}* %P) {
+ store {i32, i32} %A, {i32, i32}* %P
+ %X = bitcast {i32, i32}* %P to i8*
+ %Y = load i8* %X
+ ret i8 %Y
+}
+
+
+;;===----------------------------------------------------------------------===;;
+;; Store -> Load and Load -> Load forwarding where src and dst are different
+;; types, but where the base pointer is a must alias.
+;;===----------------------------------------------------------------------===;;
+
+;; i32 -> f32 forwarding.
+define float @coerce_mustalias1(i32 %V, i32* %P) {
+ store i32 %V, i32* %P
+
+ %P2 = bitcast i32* %P to float*
+
+ %A = load float* %P2
+ ret float %A
+; CHECK: @coerce_mustalias1
+; CHECK-NOT: load
+; CHECK: ret float
+}
+
+;; i32* -> float forwarding.
+define float @coerce_mustalias2(i32* %V, i32** %P) {
+ store i32* %V, i32** %P
+
+ %P2 = bitcast i32** %P to float*
+
+ %A = load float* %P2
+ ret float %A
+; CHECK: @coerce_mustalias2
+; CHECK-NOT: load
+; CHECK: ret float
+}
+
+;; float -> i32* forwarding.
+define i32* @coerce_mustalias3(float %V, float* %P) {
+ store float %V, float* %P
+
+ %P2 = bitcast float* %P to i32**
+
+ %A = load i32** %P2
+ ret i32* %A
+; CHECK: @coerce_mustalias3
+; CHECK-NOT: load
+; CHECK: ret i32*
+}
+
+;; i32 -> f32 load forwarding.
+define float @coerce_mustalias4(i32* %P, i1 %cond) {
+ %A = load i32* %P
+
+ %P2 = bitcast i32* %P to float*
+ %B = load float* %P2
+ br i1 %cond, label %T, label %F
+T:
+ ret float %B
+
+F:
+ %X = bitcast i32 %A to float
+ ret float %X
+
+; CHECK: @coerce_mustalias4
+; CHECK: %A = load i32* %P
+; CHECK-NOT: load
+; CHECK: ret float
+; CHECK: F:
+}
+
+;; i32 -> i8 forwarding
+define i8 @coerce_mustalias5(i32 %V, i32* %P) {
+ store i32 %V, i32* %P
+
+ %P2 = bitcast i32* %P to i8*
+
+ %A = load i8* %P2
+ ret i8 %A
+; CHECK: @coerce_mustalias5
+; CHECK-NOT: load
+; CHECK: ret i8
+}
+
+;; i64 -> float forwarding
+define float @coerce_mustalias6(i64 %V, i64* %P) {
+ store i64 %V, i64* %P
+
+ %P2 = bitcast i64* %P to float*
+
+ %A = load float* %P2
+ ret float %A
+; CHECK: @coerce_mustalias6
+; CHECK-NOT: load
+; CHECK: ret float
+}
+
+;; i64 -> i8* (32-bit) forwarding
+define i8* @coerce_mustalias7(i64 %V, i64* %P) {
+ store i64 %V, i64* %P
+
+ %P2 = bitcast i64* %P to i8**
+
+ %A = load i8** %P2
+ ret i8* %A
+; CHECK: @coerce_mustalias7
+; CHECK-NOT: load
+; CHECK: ret i8*
+}
+
+; memset -> i16 forwarding.
+define signext i16 @memset_to_i16_local(i16* %A) nounwind ssp {
+entry:
+ %conv = bitcast i16* %A to i8*
+ tail call void @llvm.memset.i64(i8* %conv, i8 1, i64 200, i32 1)
+ %arrayidx = getelementptr inbounds i16* %A, i64 42
+ %tmp2 = load i16* %arrayidx
+ ret i16 %tmp2
+; CHECK: @memset_to_i16_local
+; CHECK-NOT: load
+; CHECK: ret i16 257
+}
+
+; memset -> float forwarding.
+define float @memset_to_float_local(float* %A, i8 %Val) nounwind ssp {
+entry:
+ %conv = bitcast float* %A to i8* ; <i8*> [#uses=1]
+ tail call void @llvm.memset.i64(i8* %conv, i8 %Val, i64 400, i32 1)
+ %arrayidx = getelementptr inbounds float* %A, i64 42 ; <float*> [#uses=1]
+ %tmp2 = load float* %arrayidx ; <float> [#uses=1]
+ ret float %tmp2
+; CHECK: @memset_to_float_local
+; CHECK-NOT: load
+; CHECK: zext
+; CHECK-NEXT: shl
+; CHECK-NEXT: or
+; CHECK-NEXT: shl
+; CHECK-NEXT: or
+; CHECK-NEXT: bitcast
+; CHECK-NEXT: ret float
+}
+
+;; non-local memset -> i16 load forwarding.
+define i16 @memset_to_i16_nonlocal0(i16* %P, i1 %cond) {
+ %P3 = bitcast i16* %P to i8*
+ br i1 %cond, label %T, label %F
+T:
+ tail call void @llvm.memset.i64(i8* %P3, i8 1, i64 400, i32 1)
+ br label %Cont
+
+F:
+ tail call void @llvm.memset.i64(i8* %P3, i8 2, i64 400, i32 1)
+ br label %Cont
+
+Cont:
+ %P2 = getelementptr i16* %P, i32 4
+ %A = load i16* %P2
+ ret i16 %A
+
+; CHECK: @memset_to_i16_nonlocal0
+; CHECK: Cont:
+; CHECK-NEXT: %A = phi i16 [ 514, %F ], [ 257, %T ]
+; CHECK-NOT: load
+; CHECK: ret i16 %A
+}
+
+@GCst = constant {i32, float, i32 } { i32 42, float 14., i32 97 }
+
+; memset -> float forwarding.
+define float @memcpy_to_float_local(float* %A) nounwind ssp {
+entry:
+ %conv = bitcast float* %A to i8* ; <i8*> [#uses=1]
+ tail call void @llvm.memcpy.i64(i8* %conv, i8* bitcast ({i32, float, i32 }* @GCst to i8*), i64 12, i32 1)
+ %arrayidx = getelementptr inbounds float* %A, i64 1 ; <float*> [#uses=1]
+ %tmp2 = load float* %arrayidx ; <float> [#uses=1]
+ ret float %tmp2
+; CHECK: @memcpy_to_float_local
+; CHECK-NOT: load
+; CHECK: ret float 1.400000e+01
+}
+
+
+declare void @llvm.memset.i64(i8* nocapture, i8, i64, i32) nounwind
+declare void @llvm.memcpy.i64(i8* nocapture, i8* nocapture, i64, i32) nounwind
+
+
+
+
+;; non-local i32/float -> i8 load forwarding.
+define i8 @coerce_mustalias_nonlocal0(i32* %P, i1 %cond) {
+ %P2 = bitcast i32* %P to float*
+ %P3 = bitcast i32* %P to i8*
+ br i1 %cond, label %T, label %F
+T:
+ store i32 42, i32* %P
+ br label %Cont
+
+F:
+ store float 1.0, float* %P2
+ br label %Cont
+
+Cont:
+ %A = load i8* %P3
+ ret i8 %A
+
+; CHECK: @coerce_mustalias_nonlocal0
+; CHECK: Cont:
+; CHECK: %A = phi i8 [
+; CHECK-NOT: load
+; CHECK: ret i8 %A
+}
+
+
+;; non-local i32/float -> i8 load forwarding. This also tests that the "P3"
+;; bitcast equivalence can be properly phi translated.
+define i8 @coerce_mustalias_nonlocal1(i32* %P, i1 %cond) {
+ %P2 = bitcast i32* %P to float*
+ br i1 %cond, label %T, label %F
+T:
+ store i32 42, i32* %P
+ br label %Cont
+
+F:
+ store float 1.0, float* %P2
+ br label %Cont
+
+Cont:
+ %P3 = bitcast i32* %P to i8*
+ %A = load i8* %P3
+ ret i8 %A
+
+;; FIXME: This is disabled because this caused a miscompile in the llvm-gcc
+;; bootstrap, see r82411
+;
+; HECK: @coerce_mustalias_nonlocal1
+; HECK: Cont:
+; HECK: %A = phi i8 [
+; HECK-NOT: load
+; HECK: ret i8 %A
+}
+
+
+;; non-local i32 -> i8 partial redundancy load forwarding.
+define i8 @coerce_mustalias_pre0(i32* %P, i1 %cond) {
+ %P3 = bitcast i32* %P to i8*
+ br i1 %cond, label %T, label %F
+T:
+ store i32 42, i32* %P
+ br label %Cont
+
+F:
+ br label %Cont
+
+Cont:
+ %A = load i8* %P3
+ ret i8 %A
+
+; CHECK: @coerce_mustalias_pre0
+; CHECK: F:
+; CHECK: load i8* %P3
+; CHECK: Cont:
+; CHECK: %A = phi i8 [
+; CHECK-NOT: load
+; CHECK: ret i8 %A
+}
+
+;;===----------------------------------------------------------------------===;;
+;; Store -> Load and Load -> Load forwarding where src and dst are different
+;; types, and the reload is an offset from the store pointer.
+;;===----------------------------------------------------------------------===;;
+
+;; i32 -> i8 forwarding.
+;; PR4216
+define i8 @coerce_offset0(i32 %V, i32* %P) {
+ store i32 %V, i32* %P
+
+ %P2 = bitcast i32* %P to i8*
+ %P3 = getelementptr i8* %P2, i32 2
+
+ %A = load i8* %P3
+ ret i8 %A
+; CHECK: @coerce_offset0
+; CHECK-NOT: load
+; CHECK: ret i8
+}
+
+;; non-local i32/float -> i8 load forwarding.
+define i8 @coerce_offset_nonlocal0(i32* %P, i1 %cond) {
+ %P2 = bitcast i32* %P to float*
+ %P3 = bitcast i32* %P to i8*
+ %P4 = getelementptr i8* %P3, i32 2
+ br i1 %cond, label %T, label %F
+T:
+ store i32 42, i32* %P
+ br label %Cont
+
+F:
+ store float 1.0, float* %P2
+ br label %Cont
+
+Cont:
+ %A = load i8* %P4
+ ret i8 %A
+
+; CHECK: @coerce_offset_nonlocal0
+; CHECK: Cont:
+; CHECK: %A = phi i8 [
+; CHECK-NOT: load
+; CHECK: ret i8 %A
+}
+
+
+;; non-local i32 -> i8 partial redundancy load forwarding.
+define i8 @coerce_offset_pre0(i32* %P, i1 %cond) {
+ %P3 = bitcast i32* %P to i8*
+ %P4 = getelementptr i8* %P3, i32 2
+ br i1 %cond, label %T, label %F
+T:
+ store i32 42, i32* %P
+ br label %Cont
+
+F:
+ br label %Cont
+
+Cont:
+ %A = load i8* %P4
+ ret i8 %A
+
+; CHECK: @coerce_offset_pre0
+; CHECK: F:
+; CHECK: load i8* %P4
+; CHECK: Cont:
+; CHECK: %A = phi i8 [
+; CHECK-NOT: load
+; CHECK: ret i8 %A
+}
+
+define i32 @chained_load(i32** %p) {
+block1:
+ %z = load i32** %p
+ br i1 true, label %block2, label %block3
+
+block2:
+ %a = load i32** %p
+ br label %block4
+
+block3:
+ %b = load i32** %p
+ br label %block4
+
+block4:
+ %c = load i32** %p
+ %d = load i32* %c
+ ret i32 %d
+
+; CHECK: @chained_load
+; CHECK: %z = load i32** %p
+; CHECK-NOT: load
+; CHECK: %d = load i32* %z
+; CHECK-NEXT: ret i32 %d
+}
+
+
+declare i1 @cond() readonly
+declare i1 @cond2() readonly
+
+define i32 @phi_trans2() {
+; CHECK: @phi_trans2
+entry:
+ %P = alloca i32, i32 400
+ br label %F1
+
+F1:
+ %A = phi i32 [1, %entry], [2, %F]
+ %cond2 = call i1 @cond()
+ br i1 %cond2, label %T1, label %TY
+
+T1:
+ %P2 = getelementptr i32* %P, i32 %A
+ %x = load i32* %P2
+ %cond = call i1 @cond2()
+ br i1 %cond, label %TX, label %F
+
+F:
+ %P3 = getelementptr i32* %P, i32 2
+ store i32 17, i32* %P3
+
+ store i32 42, i32* %P2 ; Provides "P[A]".
+ br label %F1
+
+TX:
+ ; This load should not be compiled to 'ret i32 42'. An overly clever
+ ; implementation of GVN would see that we're returning 17 if the loop
+ ; executes once or 42 if it executes more than that, but we'd have to do
+ ; loop restructuring to expose this, and GVN shouldn't do this sort of CFG
+ ; transformation.
+
+; CHECK: TX:
+; CHECK: ret i32 %x
+ ret i32 %x
+TY:
+ ret i32 0
+}
+
+define i32 @phi_trans3(i32* %p) {
+; CHECK: @phi_trans3
+block1:
+ br i1 true, label %block2, label %block3
+
+block2:
+ store i32 87, i32* %p
+ br label %block4
+
+block3:
+ %p2 = getelementptr i32* %p, i32 43
+ store i32 97, i32* %p2
+ br label %block4
+
+block4:
+ %A = phi i32 [-1, %block2], [42, %block3]
+ br i1 true, label %block5, label %exit
+
+; CHECK: block4:
+; CHECK-NEXT: %D = phi i32 [ 87, %block2 ], [ 97, %block3 ]
+; CHECK-NOT: load
+
+block5:
+ %B = add i32 %A, 1
+ br i1 true, label %block6, label %exit
+
+block6:
+ %C = getelementptr i32* %p, i32 %B
+ br i1 true, label %block7, label %exit
+
+block7:
+ %D = load i32* %C
+ ret i32 %D
+
+; CHECK: block7:
+; CHECK-NEXT: ret i32 %D
+
+exit:
+ ret i32 -1
+}
+
+define i8 @phi_trans4(i8* %p) {
+; CHECK: @phi_trans4
+entry:
+ %X3 = getelementptr i8* %p, i32 192
+ store i8 192, i8* %X3
+
+ %X = getelementptr i8* %p, i32 4
+ %Y = load i8* %X
+ br label %loop
+
+loop:
+ %i = phi i32 [4, %entry], [192, %loop]
+ %X2 = getelementptr i8* %p, i32 %i
+ %Y2 = load i8* %X2
+
+; CHECK: loop:
+; CHECK-NEXT: %Y2 = phi i8 [ %Y, %entry ], [ 0, %loop ]
+; CHECK-NOT: load i8
+
+ %cond = call i1 @cond2()
+
+ %Z = bitcast i8 *%X3 to i32*
+ store i32 0, i32* %Z
+ br i1 %cond, label %loop, label %out
+
+out:
+ %R = add i8 %Y, %Y2
+ ret i8 %R
+}
+
+define i8 @phi_trans5(i8* %p) {
+; CHECK: @phi_trans5
+entry:
+
+ %X4 = getelementptr i8* %p, i32 2
+ store i8 19, i8* %X4
+
+ %X = getelementptr i8* %p, i32 4
+ %Y = load i8* %X
+ br label %loop
+
+loop:
+ %i = phi i32 [4, %entry], [3, %cont]
+ %X2 = getelementptr i8* %p, i32 %i
+ %Y2 = load i8* %X2 ; Ensure this load is not being incorrectly replaced.
+ %cond = call i1 @cond2()
+ br i1 %cond, label %cont, label %out
+
+cont:
+ %Z = getelementptr i8* %X2, i32 -1
+ %Z2 = bitcast i8 *%Z to i32*
+ store i32 50462976, i32* %Z2 ;; (1 << 8) | (2 << 16) | (3 << 24)
+
+
+; CHECK: store i32
+; CHECK-NEXT: getelementptr i8* %p, i32 3
+; CHECK-NEXT: load i8*
+ br label %loop
+
+out:
+ %R = add i8 %Y, %Y2
+ ret i8 %R
+}
+
+
+