[llvm] GVN/test: regen with UTC (NFC) (PR #111365)
Ramkumar Ramachandra via llvm-commits
llvm-commits at lists.llvm.org
Mon Oct 7 05:19:13 PDT 2024
https://github.com/artagnon created https://github.com/llvm/llvm-project/pull/111365
Regenerate tests in GVN with UpdateTestChecks, where possible.
>From a2367c4f193615e5781df0ec9a7200a389f21a99 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <ramkumar.ramachandra at codasip.com>
Date: Mon, 7 Oct 2024 13:11:27 +0100
Subject: [PATCH] GVN/test: regen with UTC (NFC)
Regenerate tests in GVN with UpdateTestChecks, where possible.
---
.../Transforms/GVN/2007-07-25-InfiniteLoop.ll | 19 +-
.../GVN/2007-07-26-InterlockingLoops.ll | 62 +-
.../Transforms/GVN/2007-07-26-PhiErasure.ll | 57 +-
.../Transforms/GVN/2007-07-31-NoDomInherit.ll | 397 ++++++++-----
.../Transforms/GVN/2007-07-31-RedundantPhi.ll | 34 +-
.../Transforms/GVN/2008-02-12-UndefLoad.ll | 28 +-
.../Transforms/GVN/2008-07-02-Unreachable.ll | 43 +-
.../Transforms/GVN/2008-12-09-SelfRemove.ll | 48 +-
.../GVN/2009-11-12-MemDepMallocBitCast.ll | 11 +-
.../GVN/2010-03-31-RedundantPHIs.ll | 30 +-
.../Transforms/GVN/2010-11-13-Simplify.ll | 10 +-
.../GVN/2011-07-07-MatchIntrinsicExtract.ll | 79 ++-
.../Transforms/GVN/2011-09-07-TypeIdFor.ll | 60 +-
...-08-30-MaskedScatterGather-inseltpoison.ll | 27 +-
.../GVN/2016-08-30-MaskedScatterGather.ll | 27 +-
llvm/test/Transforms/GVN/assume-equal.ll | 229 ++++---
llvm/test/Transforms/GVN/basic-undef-test.ll | 12 +-
llvm/test/Transforms/GVN/basic.ll | 13 +-
llvm/test/Transforms/GVN/bitcast-of-call.ll | 16 +-
llvm/test/Transforms/GVN/br-identical.ll | 26 +-
.../Transforms/GVN/callbr-loadpre-critedge.ll | 2 +-
.../GVN/callbr-scalarpre-critedge.ll | 2 +-
.../Transforms/GVN/calloc-load-removal.ll | 23 +-
llvm/test/Transforms/GVN/calls-nonlocal.ll | 100 ++--
llvm/test/Transforms/GVN/calls-readonly.ll | 35 +-
llvm/test/Transforms/GVN/cond_br.ll | 37 +-
llvm/test/Transforms/GVN/cond_br2.ll | 92 ++-
.../test/Transforms/GVN/dbg-redundant-load.ll | 35 +-
llvm/test/Transforms/GVN/debugloc.ll | 63 +-
llvm/test/Transforms/GVN/edge.ll | 224 +++++--
.../test/Transforms/GVN/fake-use-constprop.ll | 16 +-
llvm/test/Transforms/GVN/flags.ll | 14 +-
llvm/test/Transforms/GVN/fold-const-expr.ll | 14 +-
llvm/test/Transforms/GVN/fpmath.ll | 51 +-
llvm/test/Transforms/GVN/funclet.ll | 30 +-
llvm/test/Transforms/GVN/int_sideeffect.ll | 60 +-
llvm/test/Transforms/GVN/invariant.group.ll | 560 +++++++++++-------
llvm/test/Transforms/GVN/invariant.start.ll | 41 +-
llvm/test/Transforms/GVN/lifetime-simple.ll | 13 +-
llvm/test/Transforms/GVN/load-constant-mem.ll | 24 +-
.../GVN/load-from-unreachable-predecessor.ll | 15 +-
.../Transforms/GVN/malloc-load-removal.ll | 43 +-
llvm/test/Transforms/GVN/no-mem-dep-info.ll | 16 +-
llvm/test/Transforms/GVN/noalias.ll | 38 +-
.../GVN/non-integral-pointers-inseltpoison.ll | 2 +-
llvm/test/Transforms/GVN/non-local-offset.ll | 40 +-
.../GVN/phi-translate-partial-alias.ll | 18 +-
llvm/test/Transforms/GVN/pr10820.ll | 11 +-
llvm/test/Transforms/GVN/pr12979.ll | 75 ++-
llvm/test/Transforms/GVN/pr14166.ll | 17 +-
llvm/test/Transforms/GVN/pr17732.ll | 9 +-
llvm/test/Transforms/GVN/pr24426.ll | 9 +-
llvm/test/Transforms/GVN/pr25440.ll | 89 ++-
llvm/test/Transforms/GVN/pr28562.ll | 9 +-
llvm/test/Transforms/GVN/readattrs.ll | 10 +-
.../GVN/simplify-icf-cache-invalidation.ll | 27 +-
llvm/test/Transforms/GVN/stale-loop-info.ll | 23 +-
llvm/test/Transforms/GVN/tbaa.ll | 113 ++--
.../Transforms/GVN/unreachable-predecessor.ll | 31 +-
59 files changed, 2296 insertions(+), 963 deletions(-)
diff --git a/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll b/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
index 9c720049bd84a0..9b196eb0a3350e 100644
--- a/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
+++ b/llvm/test/Transforms/GVN/2007-07-25-InfiniteLoop.ll
@@ -1,15 +1,22 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
- %struct.INT2 = type { i32, i32 }
+%struct.INT2 = type { i32, i32 }
@blkshifts = external global ptr ; <ptr> [#uses=2]
define i32 @xcompact() {
+; CHECK-LABEL: define i32 @xcompact() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: store ptr null, ptr @blkshifts, align 4
+; CHECK-NEXT: br label %[[BB:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: br label %[[BB]]
+;
entry:
- store ptr null, ptr @blkshifts, align 4
- br label %bb
+ store ptr null, ptr @blkshifts, align 4
+ br label %bb
bb: ; preds = %bb, %entry
- %tmp10 = load ptr, ptr @blkshifts, align 4 ; <ptr> [#uses=0]
-; CHECK-NOT: %tmp10
- br label %bb
+ %tmp10 = load ptr, ptr @blkshifts, align 4 ; <ptr> [#uses=0]
+ br label %bb
}
diff --git a/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll b/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
index e8fb8f1087cce9..4c264c1a76d4a6 100644
--- a/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
+++ b/llvm/test/Transforms/GVN/2007-07-26-InterlockingLoops.ll
@@ -1,40 +1,60 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
@last = external global [65 x ptr]
define i32 @NextRootMove(i32 %wtm, i32 %x, i32 %y, i32 %z) {
+; CHECK-LABEL: define i32 @NextRootMove(
+; CHECK-SAME: i32 [[WTM:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[A:%.*]] = alloca ptr, align 8
+; CHECK-NEXT: [[TMP17618:%.*]] = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+; CHECK-NEXT: store ptr [[TMP17618]], ptr [[A]], align 8
+; CHECK-NEXT: br label %[[COND_TRUE116:.*]]
+; CHECK: [[COND_TRUE116]]:
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[COND_TRUE128:.*]], label %[[COND_TRUE145:.*]]
+; CHECK: [[COND_TRUE128]]:
+; CHECK-NEXT: store ptr [[TMP17618]], ptr [[A]], align 8
+; CHECK-NEXT: [[CMP1:%.*]] = icmp eq i32 [[X]], [[Z]]
+; CHECK-NEXT: br i1 [[CMP1]], label %[[BB98_BACKEDGE:.*]], label %[[RETURN_LOOPEXIT:.*]]
+; CHECK: [[BB98_BACKEDGE]]:
+; CHECK-NEXT: br label %[[COND_TRUE116]]
+; CHECK: [[COND_TRUE145]]:
+; CHECK-NEXT: store ptr [[TMP17618]], ptr [[A]], align 8
+; CHECK-NEXT: br i1 false, label %[[COND_TRUE145_BB98_BACKEDGE_CRIT_EDGE:.*]], label %[[RETURN_LOOPEXIT]]
+; CHECK: [[COND_TRUE145_BB98_BACKEDGE_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[BB98_BACKEDGE]]
+; CHECK: [[RETURN_LOOPEXIT]]:
+; CHECK-NEXT: ret i32 0
+;
entry:
- %A = alloca ptr
- %tmp17618 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
- store ptr %tmp17618, ptr %A
-; CHECK: entry:
-; CHECK-NEXT: alloca ptr
-; CHECK-NEXT: %tmp17618 = load
-; CHECK-NOT: load
-; CHECK-NOT: phi
- br label %cond_true116
+ %A = alloca ptr
+ %tmp17618 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+ store ptr %tmp17618, ptr %A
+ br label %cond_true116
cond_true116:
- %cmp = icmp eq i32 %x, %y
- br i1 %cmp, label %cond_true128, label %cond_true145
+ %cmp = icmp eq i32 %x, %y
+ br i1 %cmp, label %cond_true128, label %cond_true145
cond_true128:
- %tmp17625 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
- store ptr %tmp17625, ptr %A
- %cmp1 = icmp eq i32 %x, %z
- br i1 %cmp1 , label %bb98.backedge, label %return.loopexit
+ %tmp17625 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+ store ptr %tmp17625, ptr %A
+ %cmp1 = icmp eq i32 %x, %z
+ br i1 %cmp1 , label %bb98.backedge, label %return.loopexit
bb98.backedge:
- br label %cond_true116
+ br label %cond_true116
cond_true145:
- %tmp17631 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
- store ptr %tmp17631, ptr %A
- br i1 false, label %bb98.backedge, label %return.loopexit
+ %tmp17631 = load ptr, ptr getelementptr ([65 x ptr], ptr @last, i32 0, i32 1), align 4
+ store ptr %tmp17631, ptr %A
+ br i1 false, label %bb98.backedge, label %return.loopexit
return.loopexit:
- br label %return
+ br label %return
return:
- ret i32 0
+ ret i32 0
}
diff --git a/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll b/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll
index 6abdc122cd45ff..9fcbd581271a83 100644
--- a/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll
+++ b/llvm/test/Transforms/GVN/2007-07-26-PhiErasure.ll
@@ -1,44 +1,45 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
- %struct..0anon = type { i32 }
- %struct.FILE = type { ptr, i32, i32, i16, i16, %struct.__sbuf, i32, ptr, ptr, ptr, ptr, ptr, %struct.__sbuf, ptr, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
- %struct.__sFILEX = type opaque
- %struct.__sbuf = type { ptr, i32 }
- %struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
+%struct..0anon = type { i32 }
+%struct.FILE = type { ptr, i32, i32, i16, i16, %struct.__sbuf, i32, ptr, ptr, ptr, ptr, ptr, %struct.__sbuf, ptr, i32, [3 x i8], [1 x i8], %struct.__sbuf, i32, i64 }
+%struct.__sFILEX = type opaque
+%struct.__sbuf = type { ptr, i32 }
+%struct.rtx_def = type { i16, i8, i8, [1 x %struct..0anon] }
@n_spills = external global i32 ; <ptr> [#uses=2]
define i32 @reload(ptr %first, i32 %global, ptr %dumpfile) {
+; CHECK-LABEL: define i32 @reload(
+; CHECK-SAME: ptr [[FIRST:%.*]], i32 [[GLOBAL:%.*]], ptr [[DUMPFILE:%.*]]) {
+; CHECK-NEXT: [[COND_NEXT2835_1:.*:]]
+; CHECK-NEXT: br label %[[BB2928:.*]]
+; CHECK: [[BB2928]]:
+; CHECK-NEXT: br i1 false, label %[[BB2928_COND_NEXT2943_CRIT_EDGE:.*]], label %[[COND_TRUE2935:.*]]
+; CHECK: [[BB2928_COND_NEXT2943_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[COND_NEXT2943:.*]]
+; CHECK: [[COND_TRUE2935]]:
+; CHECK-NEXT: br label %[[COND_NEXT2943]]
+; CHECK: [[COND_NEXT2943]]:
+; CHECK-NEXT: br i1 false, label %[[BB2982_PREHEADER:.*]], label %[[BB2928]]
+; CHECK: [[BB2982_PREHEADER]]:
+; CHECK-NEXT: [[TMP298316:%.*]] = load i32, ptr @n_spills, align 4
+; CHECK-NEXT: ret i32 [[TMP298316]]
+;
cond_next2835.1: ; preds = %cond_next2861
- %tmp2922 = load i32, ptr @n_spills, align 4 ; <i32> [#uses=0]
- br label %bb2928
+ %tmp2922 = load i32, ptr @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
+ br i1 false, label %cond_next2943, label %cond_true2935
cond_true2935: ; preds = %bb2928
- br label %cond_next2943
+ br label %cond_next2943
cond_next2943: ; preds = %cond_true2935, %bb2928
- br i1 false, label %bb2982.preheader, label %bb2928
+ br i1 false, label %bb2982.preheader, label %bb2928
bb2982.preheader: ; preds = %cond_next2943
- %tmp298316 = load i32, ptr @n_spills, align 4 ; <i32> [#uses=0]
- ret i32 %tmp298316
-
+ %tmp298316 = load i32, ptr @n_spills, align 4 ; <i32> [#uses=0]
+ ret i32 %tmp298316
}
-; CHECK: define i32 @reload(ptr %first, i32 %global, ptr %dumpfile) {
-; CHECK-NEXT: cond_next2835.1:
-; CHECK-NEXT: br label %bb2928
-; CHECK: bb2928:
-; CHECK-NEXT: br i1 false, label %bb2928.cond_next2943_crit_edge, label %cond_true2935
-; CHECK: bb2928.cond_next2943_crit_edge:
-; CHECK-NEXT: br label %cond_next2943
-; CHECK: cond_true2935:
-; CHECK-NEXT: br label %cond_next2943
-; CHECK: cond_next2943:
-; CHECK-NEXT: br i1 false, label %bb2982.preheader, label %bb2928
-; CHECK: bb2982.preheader:
-; CHECK-NEXT: %tmp298316 = load i32, ptr @n_spills, align 4
-; CHECK-NEXT: ret i32 %tmp298316
-; CHECK-NEXT: }
diff --git a/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll b/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
index b56ccc128bd6bf..dd94f09a11be23 100644
--- a/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
+++ b/llvm/test/Transforms/GVN/2007-07-31-NoDomInherit.ll
@@ -1,6 +1,7 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
- %struct.anon = type { ptr, i32, i32, [3 x i32], ptr, ptr, ptr }
+%struct.anon = type { ptr, i32, i32, [3 x i32], ptr, ptr, ptr }
@debug = external constant i32 ; <ptr> [#uses=0]
@counters = external constant i32 ; <ptr> [#uses=1]
@trialx = external global [17 x i32] ; <ptr> [#uses=1]
@@ -133,182 +134,294 @@ declare i32 @increment()
declare i32 @search()
define i32 @main(i32 %argc, ptr %argv) {
+; CHECK-LABEL: define i32 @main(
+; CHECK-SAME: i32 [[ARGC:%.*]], ptr [[ARGV:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[ARGC_ADDR:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[ARGV_ADDR:%.*]] = alloca ptr, align 8
+; CHECK-NEXT: [[RETVAL:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[I:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[NUM_SOL:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TOTAL:%.*]] = alloca i32, align 4
+; CHECK-NEXT: store i32 [[ARGC]], ptr [[ARGC_ADDR]], align 4
+; CHECK-NEXT: store ptr [[ARGV]], ptr [[ARGV_ADDR]], align 8
+; CHECK-NEXT: store i32 0, ptr [[NUM_SOL]], align 4
+; CHECK-NEXT: store i32 1, ptr @numi, align 4
+; CHECK-NEXT: br label %[[BB91:.*]]
+; CHECK: [[BB:.*]]:
+; CHECK-NEXT: [[TMP3:%.*]] = call i32 (ptr, ...) @printf(ptr @.str43, i32 [[TMP1:%.*]])
+; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: br label %[[BB13:.*]]
+; CHECK: [[BB4:.*]]:
+; CHECK-NEXT: [[TMP7:%.*]] = getelementptr [17 x i32], ptr @trialx, i32 0, i32 [[TMP11:%.*]]
+; CHECK-NEXT: [[TMP8:%.*]] = load i32, ptr [[TMP7]], align 4
+; CHECK-NEXT: [[TMP9:%.*]] = call i32 @userfun(i32 [[TMP8]])
+; CHECK-NEXT: [[TMP10:%.*]] = getelementptr [17 x i32], ptr @correct_result, i32 0, i32 [[TMP11]]
+; CHECK-NEXT: store i32 [[TMP9]], ptr [[TMP10]], align 4
+; CHECK-NEXT: [[TMP12:%.*]] = add i32 [[TMP11]], 1
+; CHECK-NEXT: store i32 [[TMP12]], ptr [[I]], align 4
+; CHECK-NEXT: br label %[[BB13]]
+; CHECK: [[BB13]]:
+; CHECK-NEXT: [[TMP11]] = phi i32 [ [[TMP12]], %[[BB4]] ], [ 0, %[[BB]] ]
+; CHECK-NEXT: [[TMP15:%.*]] = icmp sle i32 [[TMP11]], 16
+; CHECK-NEXT: [[TMP1516:%.*]] = zext i1 [[TMP15]] to i32
+; CHECK-NEXT: br i1 [[TMP15]], label %[[BB4]], label %[[BB17:.*]]
+; CHECK: [[BB17]]:
+; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: br label %[[BB49:.*]]
+; CHECK: [[BB18:.*]]:
+; CHECK-NEXT: [[TMP20:%.*]] = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 [[TMP47:%.*]]
+; CHECK-NEXT: store i32 0, ptr [[TMP20]], align 4
+; CHECK-NEXT: [[TMP26:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @isa, i64 16), align 4
+; CHECK-NEXT: [[TMP28:%.*]] = getelementptr { i32, [3 x i32] }, ptr [[TMP20]], i32 0, i32 1
+; CHECK-NEXT: store i32 [[TMP26]], ptr [[TMP28]], align 4
+; CHECK-NEXT: [[TMP34:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @isa, i64 20), align 4
+; CHECK-NEXT: [[TMP37:%.*]] = getelementptr [3 x i32], ptr [[TMP28]], i32 0, i32 1
+; CHECK-NEXT: store i32 [[TMP34]], ptr [[TMP37]], align 4
+; CHECK-NEXT: [[TMP42:%.*]] = load i32, ptr getelementptr inbounds (i8, ptr @isa, i64 24), align 4
+; CHECK-NEXT: [[TMP45:%.*]] = getelementptr [3 x i32], ptr [[TMP28]], i32 0, i32 2
+; CHECK-NEXT: store i32 [[TMP42]], ptr [[TMP45]], align 4
+; CHECK-NEXT: call void @fix_operands(i32 [[TMP47]])
+; CHECK-NEXT: [[TMP48:%.*]] = add i32 [[TMP47]], 1
+; CHECK-NEXT: store i32 [[TMP48]], ptr [[I]], align 4
+; CHECK-NEXT: br label %[[BB49]]
+; CHECK: [[BB49]]:
+; CHECK-NEXT: [[TMP47]] = phi i32 [ [[TMP48]], %[[BB18]] ], [ 0, %[[BB17]] ]
+; CHECK-NEXT: [[TMP50:%.*]] = load i32, ptr @numi, align 4
+; CHECK-NEXT: [[TMP52:%.*]] = icmp slt i32 [[TMP47]], [[TMP50]]
+; CHECK-NEXT: [[TMP5253:%.*]] = zext i1 [[TMP52]] to i32
+; CHECK-NEXT: br i1 [[TMP52]], label %[[BB18]], label %[[BB55:.*]]
+; CHECK: [[BB55]]:
+; CHECK-NEXT: [[TMP56:%.*]] = call i32 @search()
+; CHECK-NEXT: store i32 [[TMP56]], ptr [[NUM_SOL]], align 4
+; CHECK-NEXT: [[TMP59:%.*]] = call i32 (ptr, ...) @printf(ptr @.str44, i32 [[TMP56]])
+; CHECK-NEXT: [[TMP60:%.*]] = load i32, ptr @counters, align 4
+; CHECK-NEXT: [[TMP61:%.*]] = icmp ne i32 [[TMP60]], 0
+; CHECK-NEXT: [[TMP6162:%.*]] = zext i1 [[TMP61]] to i32
+; CHECK-NEXT: br i1 [[TMP61]], label %[[COND_TRUE:.*]], label %[[COND_NEXT:.*]]
+; CHECK: [[COND_TRUE]]:
+; CHECK-NEXT: store i32 0, ptr [[TOTAL]], align 4
+; CHECK-NEXT: [[TMP65:%.*]] = call i32 (ptr, ...) @printf(ptr @.str45)
+; CHECK-NEXT: store i32 0, ptr [[I]], align 4
+; CHECK-NEXT: br label %[[BB79:.*]]
+; CHECK: [[BB66:.*]]:
+; CHECK-NEXT: [[TMP68:%.*]] = getelementptr [5 x i32], ptr @counter, i32 0, i32 [[TMP77:%.*]]
+; CHECK-NEXT: [[TMP69:%.*]] = load i32, ptr [[TMP68]], align 4
+; CHECK-NEXT: [[TMP71:%.*]] = call i32 (ptr, ...) @printf(ptr @.str46, i32 [[TMP69]])
+; CHECK-NEXT: [[TMP74:%.*]] = load i32, ptr [[TMP68]], align 4
+; CHECK-NEXT: [[TMP76:%.*]] = add i32 [[TMP74]], [[TMP75:%.*]]
+; CHECK-NEXT: store i32 [[TMP76]], ptr [[TOTAL]], align 4
+; CHECK-NEXT: [[TMP78:%.*]] = add i32 [[TMP77]], 1
+; CHECK-NEXT: store i32 [[TMP78]], ptr [[I]], align 4
+; CHECK-NEXT: br label %[[BB79]]
+; CHECK: [[BB79]]:
+; CHECK-NEXT: [[TMP75]] = phi i32 [ [[TMP76]], %[[BB66]] ], [ 0, %[[COND_TRUE]] ]
+; CHECK-NEXT: [[TMP77]] = phi i32 [ [[TMP78]], %[[BB66]] ], [ 0, %[[COND_TRUE]] ]
+; CHECK-NEXT: [[TMP80:%.*]] = load i32, ptr @numi, align 4
+; CHECK-NEXT: [[TMP82:%.*]] = icmp slt i32 [[TMP77]], [[TMP80]]
+; CHECK-NEXT: [[TMP8283:%.*]] = zext i1 [[TMP82]] to i32
+; CHECK-NEXT: br i1 [[TMP82]], label %[[BB66]], label %[[BB85:.*]]
+; CHECK: [[BB85]]:
+; CHECK-NEXT: [[TMP88:%.*]] = call i32 (ptr, ...) @printf(ptr @.str47, i32 [[TMP75]])
+; CHECK-NEXT: br label %[[COND_NEXT]]
+; CHECK: [[COND_NEXT]]:
+; CHECK-NEXT: [[TMP89:%.*]] = load i32, ptr @numi, align 4
+; CHECK-NEXT: [[TMP90:%.*]] = add i32 [[TMP89]], 1
+; CHECK-NEXT: store i32 [[TMP90]], ptr @numi, align 4
+; CHECK-NEXT: br label %[[BB91]]
+; CHECK: [[BB91]]:
+; CHECK-NEXT: [[TMP98:%.*]] = phi i32 [ [[TMP56]], %[[COND_NEXT]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: [[TMP1]] = phi i32 [ [[TMP90]], %[[COND_NEXT]] ], [ 1, %[[ENTRY]] ]
+; CHECK-NEXT: [[TMP93:%.*]] = icmp sgt i32 [[TMP1]], 5
+; CHECK-NEXT: [[TMP9394:%.*]] = zext i1 [[TMP93]] to i32
+; CHECK-NEXT: br i1 [[TMP93]], label %[[COND_TRUE96:.*]], label %[[COND_NEXT97:.*]]
+; CHECK: [[COND_TRUE96]]:
+; CHECK-NEXT: br label %[[BB102:.*]]
+; CHECK: [[COND_NEXT97]]:
+; CHECK-NEXT: [[TMP99:%.*]] = icmp eq i32 [[TMP98]], 0
+; CHECK-NEXT: [[TMP99100:%.*]] = zext i1 [[TMP99]] to i32
+; CHECK-NEXT: br i1 [[TMP99]], label %[[BB]], label %[[BB102]]
+; CHECK: [[BB102]]:
+; CHECK-NEXT: store i32 0, ptr [[TMP]], align 4
+; CHECK-NEXT: store i32 0, ptr [[RETVAL]], align 4
+; CHECK-NEXT: ret i32 0
+;
entry:
- %argc_addr = alloca i32 ; <ptr> [#uses=1]
- %argv_addr = alloca ptr ; <ptr> [#uses=1]
- %retval = alloca i32, align 4 ; <ptr> [#uses=2]
- %tmp = alloca i32, align 4 ; <ptr> [#uses=2]
- %i = alloca i32, align 4 ; <ptr> [#uses=21]
- %num_sol = alloca i32, align 4 ; <ptr> [#uses=4]
- %total = alloca i32, align 4 ; <ptr> [#uses=4]
- %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
- store i32 %argc, ptr %argc_addr
- store ptr %argv, ptr %argv_addr
- store i32 0, ptr %num_sol
- store i32 1, ptr @numi
- br label %bb91
+ %argc_addr = alloca i32 ; <ptr> [#uses=1]
+ %argv_addr = alloca ptr ; <ptr> [#uses=1]
+ %retval = alloca i32, align 4 ; <ptr> [#uses=2]
+ %tmp = alloca i32, align 4 ; <ptr> [#uses=2]
+ %i = alloca i32, align 4 ; <ptr> [#uses=21]
+ %num_sol = alloca i32, align 4 ; <ptr> [#uses=4]
+ %total = alloca i32, align 4 ; <ptr> [#uses=4]
+ %"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
+ store i32 %argc, ptr %argc_addr
+ store ptr %argv, ptr %argv_addr
+ store i32 0, ptr %num_sol
+ store i32 1, ptr @numi
+ br label %bb91
bb: ; preds = %cond_next97
- %tmp1 = load i32, ptr @numi ; <i32> [#uses=1]
- %tmp2 = getelementptr [44 x i8], ptr @.str43, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp3 = call i32 (ptr, ...) @printf( ptr %tmp2, i32 %tmp1 ) ; <i32> [#uses=0]
- store i32 0, ptr %i
- br label %bb13
+ %tmp1 = load i32, ptr @numi ; <i32> [#uses=1]
+ %tmp2 = getelementptr [44 x i8], ptr @.str43, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp3 = call i32 (ptr, ...) @printf( ptr %tmp2, i32 %tmp1 ) ; <i32> [#uses=0]
+ store i32 0, ptr %i
+ br label %bb13
bb4: ; preds = %bb13
- %tmp5 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp6 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp7 = getelementptr [17 x i32], ptr @trialx, i32 0, i32 %tmp6 ; <ptr> [#uses=1]
- %tmp8 = load i32, ptr %tmp7 ; <i32> [#uses=1]
- %tmp9 = call i32 @userfun( i32 %tmp8 ) ; <i32> [#uses=1]
- %tmp10 = getelementptr [17 x i32], ptr @correct_result, i32 0, i32 %tmp5 ; <ptr> [#uses=1]
- store i32 %tmp9, ptr %tmp10
- %tmp11 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp12 = add i32 %tmp11, 1 ; <i32> [#uses=1]
- store i32 %tmp12, ptr %i
- br label %bb13
+ %tmp5 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp6 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp7 = getelementptr [17 x i32], ptr @trialx, i32 0, i32 %tmp6 ; <ptr> [#uses=1]
+ %tmp8 = load i32, ptr %tmp7 ; <i32> [#uses=1]
+ %tmp9 = call i32 @userfun( i32 %tmp8 ) ; <i32> [#uses=1]
+ %tmp10 = getelementptr [17 x i32], ptr @correct_result, i32 0, i32 %tmp5 ; <ptr> [#uses=1]
+ store i32 %tmp9, ptr %tmp10
+ %tmp11 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp12 = add i32 %tmp11, 1 ; <i32> [#uses=1]
+ store i32 %tmp12, ptr %i
+ br label %bb13
bb13: ; preds = %bb4, %bb
- %tmp14 = load i32, ptr %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
+ %tmp14 = load i32, ptr %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, ptr %i
- br label %bb49
+ store i32 0, ptr %i
+ br label %bb49
bb18: ; preds = %bb49
- %tmp19 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp20 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp19 ; <ptr> [#uses=1]
- %tmp21 = getelementptr { i32, [3 x i32] }, ptr %tmp20, i32 0, i32 0 ; <ptr> [#uses=1]
- store i32 0, ptr %tmp21
- %tmp22 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp23 = getelementptr [13 x %struct.anon], ptr @isa, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp24 = getelementptr %struct.anon, ptr %tmp23, i32 0, i32 3 ; <ptr> [#uses=1]
- %tmp25 = getelementptr [3 x i32], ptr %tmp24, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp26 = load i32, ptr %tmp25 ; <i32> [#uses=1]
- %tmp27 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp22 ; <ptr> [#uses=1]
- %tmp28 = getelementptr { i32, [3 x i32] }, ptr %tmp27, i32 0, i32 1 ; <ptr> [#uses=1]
- %tmp29 = getelementptr [3 x i32], ptr %tmp28, i32 0, i32 0 ; <ptr> [#uses=1]
- store i32 %tmp26, ptr %tmp29
- %tmp30 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp31 = getelementptr [13 x %struct.anon], ptr @isa, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp32 = getelementptr %struct.anon, ptr %tmp31, i32 0, i32 3 ; <ptr> [#uses=1]
- %tmp33 = getelementptr [3 x i32], ptr %tmp32, i32 0, i32 1 ; <ptr> [#uses=1]
- %tmp34 = load i32, ptr %tmp33 ; <i32> [#uses=1]
- %tmp35 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp30 ; <ptr> [#uses=1]
- %tmp36 = getelementptr { i32, [3 x i32] }, ptr %tmp35, i32 0, i32 1 ; <ptr> [#uses=1]
- %tmp37 = getelementptr [3 x i32], ptr %tmp36, i32 0, i32 1 ; <ptr> [#uses=1]
- store i32 %tmp34, ptr %tmp37
- %tmp38 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp39 = getelementptr [13 x %struct.anon], ptr @isa, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp40 = getelementptr %struct.anon, ptr %tmp39, i32 0, i32 3 ; <ptr> [#uses=1]
- %tmp41 = getelementptr [3 x i32], ptr %tmp40, i32 0, i32 2 ; <ptr> [#uses=1]
- %tmp42 = load i32, ptr %tmp41 ; <i32> [#uses=1]
- %tmp43 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp38 ; <ptr> [#uses=1]
- %tmp44 = getelementptr { i32, [3 x i32] }, ptr %tmp43, i32 0, i32 1 ; <ptr> [#uses=1]
- %tmp45 = getelementptr [3 x i32], ptr %tmp44, i32 0, i32 2 ; <ptr> [#uses=1]
- store i32 %tmp42, ptr %tmp45
- %tmp46 = load i32, ptr %i ; <i32> [#uses=1]
- call void @fix_operands( i32 %tmp46 )
- %tmp47 = load i32, ptr %i ; <i32> [#uses=1]
-; CHECK: %tmp47 = phi i32 [ %tmp48, %bb18 ], [ 0, %bb17 ]
- %tmp48 = add i32 %tmp47, 1 ; <i32> [#uses=1]
- store i32 %tmp48, ptr %i
- br label %bb49
+ %tmp19 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp20 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp19 ; <ptr> [#uses=1]
+ %tmp21 = getelementptr { i32, [3 x i32] }, ptr %tmp20, i32 0, i32 0 ; <ptr> [#uses=1]
+ store i32 0, ptr %tmp21
+ %tmp22 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp23 = getelementptr [13 x %struct.anon], ptr @isa, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp24 = getelementptr %struct.anon, ptr %tmp23, i32 0, i32 3 ; <ptr> [#uses=1]
+ %tmp25 = getelementptr [3 x i32], ptr %tmp24, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp26 = load i32, ptr %tmp25 ; <i32> [#uses=1]
+ %tmp27 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp22 ; <ptr> [#uses=1]
+ %tmp28 = getelementptr { i32, [3 x i32] }, ptr %tmp27, i32 0, i32 1 ; <ptr> [#uses=1]
+ %tmp29 = getelementptr [3 x i32], ptr %tmp28, i32 0, i32 0 ; <ptr> [#uses=1]
+ store i32 %tmp26, ptr %tmp29
+ %tmp30 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp31 = getelementptr [13 x %struct.anon], ptr @isa, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp32 = getelementptr %struct.anon, ptr %tmp31, i32 0, i32 3 ; <ptr> [#uses=1]
+ %tmp33 = getelementptr [3 x i32], ptr %tmp32, i32 0, i32 1 ; <ptr> [#uses=1]
+ %tmp34 = load i32, ptr %tmp33 ; <i32> [#uses=1]
+ %tmp35 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp30 ; <ptr> [#uses=1]
+ %tmp36 = getelementptr { i32, [3 x i32] }, ptr %tmp35, i32 0, i32 1 ; <ptr> [#uses=1]
+ %tmp37 = getelementptr [3 x i32], ptr %tmp36, i32 0, i32 1 ; <ptr> [#uses=1]
+ store i32 %tmp34, ptr %tmp37
+ %tmp38 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp39 = getelementptr [13 x %struct.anon], ptr @isa, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp40 = getelementptr %struct.anon, ptr %tmp39, i32 0, i32 3 ; <ptr> [#uses=1]
+ %tmp41 = getelementptr [3 x i32], ptr %tmp40, i32 0, i32 2 ; <ptr> [#uses=1]
+ %tmp42 = load i32, ptr %tmp41 ; <i32> [#uses=1]
+ %tmp43 = getelementptr [5 x { i32, [3 x i32] }], ptr @pgm, i32 0, i32 %tmp38 ; <ptr> [#uses=1]
+ %tmp44 = getelementptr { i32, [3 x i32] }, ptr %tmp43, i32 0, i32 1 ; <ptr> [#uses=1]
+ %tmp45 = getelementptr [3 x i32], ptr %tmp44, i32 0, i32 2 ; <ptr> [#uses=1]
+ store i32 %tmp42, ptr %tmp45
+ %tmp46 = load i32, ptr %i ; <i32> [#uses=1]
+ call void @fix_operands( i32 %tmp46 )
+ %tmp47 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp48 = add i32 %tmp47, 1 ; <i32> [#uses=1]
+ store i32 %tmp48, ptr %i
+ br label %bb49
bb49: ; preds = %bb18, %bb17
- %tmp50 = load i32, ptr @numi ; <i32> [#uses=1]
- %tmp51 = load i32, ptr %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
+ %tmp50 = load i32, ptr @numi ; <i32> [#uses=1]
+ %tmp51 = load i32, ptr %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, ptr %num_sol
- %tmp57 = getelementptr [21 x i8], ptr @.str44, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp58 = load i32, ptr %num_sol ; <i32> [#uses=1]
- %tmp59 = call i32 (ptr, ...) @printf( ptr %tmp57, i32 %tmp58 ) ; <i32> [#uses=0]
- %tmp60 = load i32, ptr @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
+ %tmp56 = call i32 @search( ) ; <i32> [#uses=1]
+ store i32 %tmp56, ptr %num_sol
+ %tmp57 = getelementptr [21 x i8], ptr @.str44, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp58 = load i32, ptr %num_sol ; <i32> [#uses=1]
+ %tmp59 = call i32 (ptr, ...) @printf( ptr %tmp57, i32 %tmp58 ) ; <i32> [#uses=0]
+ %tmp60 = load i32, ptr @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, ptr %total
- %tmp64 = getelementptr [12 x i8], ptr @.str45, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp65 = call i32 (ptr, ...) @printf( ptr %tmp64 ) ; <i32> [#uses=0]
- store i32 0, ptr %i
- br label %bb79
+ store i32 0, ptr %total
+ %tmp64 = getelementptr [12 x i8], ptr @.str45, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp65 = call i32 (ptr, ...) @printf( ptr %tmp64 ) ; <i32> [#uses=0]
+ store i32 0, ptr %i
+ br label %bb79
bb66: ; preds = %bb79
- %tmp67 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp68 = getelementptr [5 x i32], ptr @counter, i32 0, i32 %tmp67 ; <ptr> [#uses=1]
- %tmp69 = load i32, ptr %tmp68 ; <i32> [#uses=1]
- %tmp70 = getelementptr [5 x i8], ptr @.str46, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp71 = call i32 (ptr, ...) @printf( ptr %tmp70, i32 %tmp69 ) ; <i32> [#uses=0]
- %tmp72 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp73 = getelementptr [5 x i32], ptr @counter, i32 0, i32 %tmp72 ; <ptr> [#uses=1]
- %tmp74 = load i32, ptr %tmp73 ; <i32> [#uses=1]
- %tmp75 = load i32, ptr %total ; <i32> [#uses=1]
- %tmp76 = add i32 %tmp74, %tmp75 ; <i32> [#uses=1]
- store i32 %tmp76, ptr %total
- %tmp77 = load i32, ptr %i ; <i32> [#uses=1]
- %tmp78 = add i32 %tmp77, 1 ; <i32> [#uses=1]
- store i32 %tmp78, ptr %i
- br label %bb79
+ %tmp67 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp68 = getelementptr [5 x i32], ptr @counter, i32 0, i32 %tmp67 ; <ptr> [#uses=1]
+ %tmp69 = load i32, ptr %tmp68 ; <i32> [#uses=1]
+ %tmp70 = getelementptr [5 x i8], ptr @.str46, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp71 = call i32 (ptr, ...) @printf( ptr %tmp70, i32 %tmp69 ) ; <i32> [#uses=0]
+ %tmp72 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp73 = getelementptr [5 x i32], ptr @counter, i32 0, i32 %tmp72 ; <ptr> [#uses=1]
+ %tmp74 = load i32, ptr %tmp73 ; <i32> [#uses=1]
+ %tmp75 = load i32, ptr %total ; <i32> [#uses=1]
+ %tmp76 = add i32 %tmp74, %tmp75 ; <i32> [#uses=1]
+ store i32 %tmp76, ptr %total
+ %tmp77 = load i32, ptr %i ; <i32> [#uses=1]
+ %tmp78 = add i32 %tmp77, 1 ; <i32> [#uses=1]
+ store i32 %tmp78, ptr %i
+ br label %bb79
bb79: ; preds = %bb66, %cond_true
- %tmp80 = load i32, ptr @numi ; <i32> [#uses=1]
- %tmp81 = load i32, ptr %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
+ %tmp80 = load i32, ptr @numi ; <i32> [#uses=1]
+ %tmp81 = load i32, ptr %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], ptr @.str47, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp87 = load i32, ptr %total ; <i32> [#uses=1]
- %tmp88 = call i32 (ptr, ...) @printf( ptr %tmp86, i32 %tmp87 ) ; <i32> [#uses=0]
- br label %cond_next
+ %tmp86 = getelementptr [12 x i8], ptr @.str47, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp87 = load i32, ptr %total ; <i32> [#uses=1]
+ %tmp88 = call i32 (ptr, ...) @printf( ptr %tmp86, i32 %tmp87 ) ; <i32> [#uses=0]
+ br label %cond_next
cond_next: ; preds = %bb85, %bb55
- %tmp89 = load i32, ptr @numi ; <i32> [#uses=1]
- %tmp90 = add i32 %tmp89, 1 ; <i32> [#uses=1]
- store i32 %tmp90, ptr @numi
- br label %bb91
+ %tmp89 = load i32, ptr @numi ; <i32> [#uses=1]
+ %tmp90 = add i32 %tmp89, 1 ; <i32> [#uses=1]
+ store i32 %tmp90, ptr @numi
+ br label %bb91
bb91: ; preds = %cond_next, %entry
- %tmp92 = load i32, ptr @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
+ %tmp92 = load i32, ptr @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
+ br label %bb102
cond_next97: ; preds = %bb91
- %tmp98 = load i32, ptr %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
+ %tmp98 = load i32, ptr %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, ptr %tmp
- %tmp103 = load i32, ptr %tmp ; <i32> [#uses=1]
- store i32 %tmp103, ptr %retval
- br label %return
+ store i32 0, ptr %tmp
+ %tmp103 = load i32, ptr %tmp ; <i32> [#uses=1]
+ store i32 %tmp103, ptr %retval
+ br label %return
return: ; preds = %bb102
- %retval104 = load i32, ptr %retval ; <i32> [#uses=1]
- ret i32 %retval104
+ %retval104 = load i32, ptr %retval ; <i32> [#uses=1]
+ ret i32 %retval104
}
declare i32 @userfun(i32)
diff --git a/llvm/test/Transforms/GVN/2007-07-31-RedundantPhi.ll b/llvm/test/Transforms/GVN/2007-07-31-RedundantPhi.ll
index b05aebfa8f451a..564a57d6b88612 100644
--- a/llvm/test/Transforms/GVN/2007-07-31-RedundantPhi.ll
+++ b/llvm/test/Transforms/GVN/2007-07-31-RedundantPhi.ll
@@ -1,23 +1,41 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
@img_width = external global i16 ; <ptr> [#uses=2]
define i32 @smpUMHEXBipredIntegerPelBlockMotionSearch(ptr %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, ptr %mv_x, ptr %mv_y, ptr %s_mv_x, ptr %s_mv_y, i32 %search_range, i32 %min_mcost, i32 %lambda_factor) {
+; CHECK-LABEL: define i32 @smpUMHEXBipredIntegerPelBlockMotionSearch(
+; CHECK-SAME: ptr [[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:%.*]], ptr [[MV_X:%.*]], ptr [[MV_Y:%.*]], ptr [[S_MV_X:%.*]], ptr [[S_MV_Y:%.*]], i32 [[SEARCH_RANGE:%.*]], i32 [[MIN_MCOST:%.*]], i32 [[LAMBDA_FACTOR:%.*]]) {
+; CHECK-NEXT: [[COND_NEXT143:.*:]]
+; CHECK-NEXT: store i16 0, ptr @img_width, align 2
+; CHECK-NEXT: br i1 false, label %[[COND_NEXT143_COND_NEXT449_CRIT_EDGE:.*]], label %[[COND_FALSE434:.*]]
+; CHECK: [[COND_NEXT143_COND_NEXT449_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[COND_NEXT449:.*]]
+; CHECK: [[COND_FALSE434]]:
+; CHECK-NEXT: br label %[[COND_NEXT449]]
+; CHECK: [[COND_NEXT449]]:
+; CHECK-NEXT: br i1 false, label %[[COND_NEXT449_COND_NEXT698_CRIT_EDGE:.*]], label %[[COND_FALSE470:.*]]
+; CHECK: [[COND_NEXT449_COND_NEXT698_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[COND_NEXT698:.*]]
+; CHECK: [[COND_FALSE470]]:
+; CHECK-NEXT: br label %[[COND_NEXT698]]
+; CHECK: [[COND_NEXT698]]:
+; CHECK-NEXT: ret i32 0
+;
cond_next143: ; preds = %entry
- store i16 0, ptr @img_width, align 2
- br i1 false, label %cond_next449, label %cond_false434
+ store i16 0, ptr @img_width, align 2
+ br i1 false, label %cond_next449, label %cond_false434
cond_false434: ; preds = %cond_true415
- br label %cond_next449
+ br label %cond_next449
cond_next449: ; preds = %cond_false434, %cond_true415
- br i1 false, label %cond_next698, label %cond_false470
+ br i1 false, label %cond_next698, label %cond_false470
cond_false470: ; preds = %cond_next449
- br label %cond_next698
+ br label %cond_next698
cond_next698: ; preds = %cond_true492
- %tmp701 = load i16, ptr @img_width, align 2 ; <i16> [#uses=0]
-; CHECK-NOT: %tmp701 =
- ret i32 0
+ %tmp701 = load i16, ptr @img_width, align 2 ; <i16> [#uses=0]
+ ret i32 0
}
diff --git a/llvm/test/Transforms/GVN/2008-02-12-UndefLoad.ll b/llvm/test/Transforms/GVN/2008-02-12-UndefLoad.ll
index b9ddf5e8ad184c..1245540ca9b7bc 100644
--- a/llvm/test/Transforms/GVN/2008-02-12-UndefLoad.ll
+++ b/llvm/test/Transforms/GVN/2008-02-12-UndefLoad.ll
@@ -1,20 +1,28 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
; PR1996
%struct.anon = type { i32, i8, i8, i8, i8 }
define i32 @a() {
+; CHECK-LABEL: define i32 @a() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[C:%.*]] = alloca [[STRUCT_ANON:%.*]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = getelementptr i32, ptr [[C]], i32 1
+; CHECK-NEXT: store i32 -21, ptr [[TMP1]], align 4
+; CHECK-NEXT: [[CALL:%.*]] = call i32 (...) @x(ptr [[C]])
+; CHECK-NEXT: ret i32 undef
+;
entry:
- %c = alloca %struct.anon ; <ptr> [#uses=2]
- %tmp = getelementptr %struct.anon, ptr %c, i32 0, i32 0 ; <ptr> [#uses=1]
- %tmp1 = getelementptr i32, ptr %tmp, i32 1 ; <ptr> [#uses=2]
- %tmp2 = load i32, ptr %tmp1, align 4 ; <i32> [#uses=1]
-; CHECK-NOT: load
- %tmp3 = or i32 %tmp2, 11 ; <i32> [#uses=1]
- %tmp4 = and i32 %tmp3, -21 ; <i32> [#uses=1]
- store i32 %tmp4, ptr %tmp1, align 4
- %call = call i32 (...) @x( ptr %c ) ; <i32> [#uses=0]
- ret i32 undef
+ %c = alloca %struct.anon ; <ptr> [#uses=2]
+ %tmp = getelementptr %struct.anon, ptr %c, i32 0, i32 0 ; <ptr> [#uses=1]
+ %tmp1 = getelementptr i32, ptr %tmp, i32 1 ; <ptr> [#uses=2]
+ %tmp2 = load i32, ptr %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, ptr %tmp1, align 4
+ %call = call i32 (...) @x( ptr %c ) ; <i32> [#uses=0]
+ ret i32 undef
}
diff --git a/llvm/test/Transforms/GVN/2008-07-02-Unreachable.ll b/llvm/test/Transforms/GVN/2008-07-02-Unreachable.ll
index e463264c6918a1..539011d979b2e6 100644
--- a/llvm/test/Transforms/GVN/2008-07-02-Unreachable.ll
+++ b/llvm/test/Transforms/GVN/2008-07-02-Unreachable.ll
@@ -1,36 +1,53 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
; PR2503
@g_3 = external global i8 ; <ptr> [#uses=2]
define i8 @func_1(i32 %x, i32 %y) nounwind {
+; CHECK-LABEL: define i8 @func_1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], [[Y]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[IFELSE:.*]], label %[[IFTHEN:.*]]
+; CHECK: [[IFTHEN]]:
+; CHECK-NEXT: ret i8 0
+; CHECK: [[IFELSE]]:
+; CHECK-NEXT: [[TMP3:%.*]] = load i8, ptr @g_3, align 1
+; CHECK-NEXT: store i8 [[TMP3]], ptr [[A]], align 1
+; CHECK-NEXT: br label %[[AFTERFOR:.*]]
+; CHECK: [[FORBODY:.*]]:
+; CHECK-NEXT: br i1 false, label %[[AFTERFOR]], label %[[FORBODY]]
+; CHECK: [[AFTERFOR]]:
+; CHECK-NEXT: ret i8 [[TMP3]]
+;
entry:
%A = alloca i8
- %cmp = icmp eq i32 %x, %y
- br i1 %cmp, label %ifelse, label %ifthen
+ %cmp = icmp eq i32 %x, %y
+ br i1 %cmp, label %ifelse, label %ifthen
ifthen: ; preds = %entry
- br label %ifend
+ br label %ifend
ifelse: ; preds = %entry
- %tmp3 = load i8, ptr @g_3 ; <i8> [#uses=0]
- store i8 %tmp3, ptr %A
- br label %afterfor
+ %tmp3 = load i8, ptr @g_3 ; <i8> [#uses=0]
+ store i8 %tmp3, ptr %A
+ br label %afterfor
forcond: ; preds = %forinc
- br i1 false, label %afterfor, label %forbody
+ br i1 false, label %afterfor, label %forbody
forbody: ; preds = %forcond
- br label %forinc
+ br label %forinc
forinc: ; preds = %forbody
- br label %forcond
+ br label %forcond
afterfor: ; preds = %forcond, %forcond.thread
- %tmp10 = load i8, ptr @g_3 ; <i8> [#uses=0]
- ret i8 %tmp10
-; CHECK: ret i8 %tmp3
+ %tmp10 = load i8, ptr @g_3 ; <i8> [#uses=0]
+ ret i8 %tmp10
ifend: ; preds = %afterfor, %ifthen
- ret i8 0
+ ret i8 0
}
diff --git a/llvm/test/Transforms/GVN/2008-12-09-SelfRemove.ll b/llvm/test/Transforms/GVN/2008-12-09-SelfRemove.ll
index 3d02d67763bd3d..b05e41888262ff 100644
--- a/llvm/test/Transforms/GVN/2008-12-09-SelfRemove.ll
+++ b/llvm/test/Transforms/GVN/2008-12-09-SelfRemove.ll
@@ -1,38 +1,40 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=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-darwin9.5"
- %struct.anon = type { ptr, i32 }
- %struct.d_print_info = type { i32, ptr, i32, i32, ptr, ptr, i32 }
- %struct.d_print_mod = type { ptr, ptr, i32, ptr }
- %struct.d_print_template = type { ptr, ptr }
- %struct.demangle_component = type { i32, { %struct.anon } }
+ %struct.anon = type { ptr, i32 }
+ %struct.d_print_info = type { i32, ptr, i32, i32, ptr, ptr, i32 }
+ %struct.d_print_mod = type { ptr, ptr, i32, ptr }
+ %struct.d_print_template = type { ptr, ptr }
+ %struct.demangle_component = type { i32, { %struct.anon } }
define void @d_print_mod_list(ptr %dpi, ptr %mods, i32 %suffix) nounwind {
+; CHECK-LABEL: define void @d_print_mod_list(
+; CHECK-SAME: ptr [[DPI:%.*]], ptr [[MODS:%.*]], i32 [[SUFFIX:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = getelementptr [[STRUCT_D_PRINT_INFO:%.*]], ptr [[DPI]], i32 0, i32 1
+; CHECK-NEXT: br i1 false, label %[[RETURN:.*]], label %[[BB:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: br label %[[BB21:.*]]
+; CHECK: [[BB21]]:
+; CHECK-NEXT: br label %[[BB21]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
- %0 = getelementptr %struct.d_print_info, ptr %dpi, i32 0, i32 1 ; <ptr> [#uses=1]
- br i1 false, label %return, label %bb
+ %0 = getelementptr %struct.d_print_info, ptr %dpi, i32 0, i32 1 ; <ptr> [#uses=1]
+ br i1 false, label %return, label %bb
bb: ; preds = %entry
- %1 = load ptr, ptr %0, align 4 ; <ptr> [#uses=0]
- %2 = getelementptr %struct.d_print_info, ptr %dpi, i32 0, i32 1 ; <ptr> [#uses=0]
- br label %bb21
+ %1 = load ptr, ptr %0, align 4 ; <ptr> [#uses=0]
+ %2 = getelementptr %struct.d_print_info, ptr %dpi, i32 0, i32 1 ; <ptr> [#uses=0]
+ br label %bb21
bb21: ; preds = %bb21, %bb
- br label %bb21
+ br label %bb21
return: ; preds = %entry
- ret void
+ ret void
}
-; CHECK: define void @d_print_mod_list(ptr %dpi, ptr %mods, i32 %suffix) #0 {
-; CHECK: entry:
-; CHECK: %0 = getelementptr %struct.d_print_info, ptr %dpi, i32 0, i32 1
-; CHECK: br i1 false, label %return, label %bb
-; CHECK: bb:
-; CHECK: br label %bb21
-; CHECK: bb21:
-; CHECK: br label %bb21
-; CHECK: return:
-; CHECK: ret void
-; CHECK: }
diff --git a/llvm/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll b/llvm/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll
index f2d4fa9d378448..f60215b88bf916 100644
--- a/llvm/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll
+++ b/llvm/test/Transforms/GVN/2009-11-12-MemDepMallocBitCast.ll
@@ -1,14 +1,19 @@
-; Test to make sure malloc's bitcast does not block detection of a store
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; 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 -passes=gvn -S | FileCheck %s
define i64 @test() {
+; CHECK-LABEL: define i64 @test() {
+; CHECK-NEXT: [[TMP1:%.*]] = tail call ptr @malloc(i64 mul (i64 ptrtoint (ptr getelementptr (i64, ptr null, i64 1) to i64), i64 4))
+; CHECK-NEXT: store i8 42, ptr [[TMP1]], align 1
+; CHECK-NEXT: [[Y:%.*]] = load i64, ptr [[TMP1]], align 4
+; CHECK-NEXT: ret i64 [[Y]]
+;
%1 = tail call ptr @malloc(i64 mul (i64 4, i64 ptrtoint (ptr getelementptr (i64, ptr null, i64 1) to i64))) ; <ptr> [#uses=2]
store i8 42, ptr %1
%Y = load i64, ptr %1 ; <i64> [#uses=1]
ret i64 %Y
-; CHECK: %Y = load i64, ptr %1
-; CHECK: ret i64 %Y
}
declare noalias ptr @malloc(i64)
diff --git a/llvm/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll b/llvm/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
index ca48a12ef6d9e2..01eb81566df5de 100644
--- a/llvm/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
+++ b/llvm/test/Transforms/GVN/2010-03-31-RedundantPHIs.ll
@@ -1,9 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
-; CHECK-NOT: load
-; CHECK-NOT: phi
-
define ptr @cat(ptr %s1, ...) nounwind {
+; CHECK-LABEL: define ptr @cat(
+; CHECK-SAME: ptr [[S1:%.*]], ...) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br i1 undef, label %[[BB:.*]], label %[[BB3:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: unreachable
+; CHECK: [[BB3]]:
+; CHECK-NEXT: store ptr undef, ptr undef, align 4
+; CHECK-NEXT: br i1 undef, label %[[BB5:.*]], label %[[BB6:.*]]
+; CHECK: [[BB5]]:
+; CHECK-NEXT: unreachable
+; CHECK: [[BB6]]:
+; CHECK-NEXT: br label %[[BB12:.*]]
+; CHECK: [[BB8:.*]]:
+; CHECK-NEXT: br i1 undef, label %[[BB9:.*]], label %[[BB10:.*]]
+; CHECK: [[BB9]]:
+; CHECK-NEXT: br label %[[BB11:.*]]
+; CHECK: [[BB10]]:
+; CHECK-NEXT: br label %[[BB11]]
+; CHECK: [[BB11]]:
+; CHECK-NEXT: br label %[[BB12]]
+; CHECK: [[BB12]]:
+; CHECK-NEXT: br i1 undef, label %[[BB8]], label %[[BB13:.*]]
+; CHECK: [[BB13]]:
+; CHECK-NEXT: ret ptr undef
+;
entry:
br i1 undef, label %bb, label %bb3
diff --git a/llvm/test/Transforms/GVN/2010-11-13-Simplify.ll b/llvm/test/Transforms/GVN/2010-11-13-Simplify.ll
index aabd083d352e1f..4b8968c8a18bf8 100644
--- a/llvm/test/Transforms/GVN/2010-11-13-Simplify.ll
+++ b/llvm/test/Transforms/GVN/2010-11-13-Simplify.ll
@@ -1,9 +1,14 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
declare i32 @foo(i32) readnone
define i1 @bar() {
-; CHECK-LABEL: @bar(
+; CHECK-LABEL: define i1 @bar() {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(i32 0) #[[ATTR0:[0-9]+]]
+; CHECK-NEXT: [[X:%.*]] = call i32 @foo(i32 [[A]]) #[[ATTR0]]
+; CHECK-NEXT: ret i1 true
+;
%a = call i32 @foo (i32 0) readnone
%b = call i32 @foo (i32 0) readnone
%c = and i32 %a, %b
@@ -11,5 +16,4 @@ define i1 @bar() {
%y = call i32 @foo (i32 %c) readnone
%z = icmp eq i32 %x, %y
ret i1 %z
-; CHECK: ret i1 true
-}
+}
diff --git a/llvm/test/Transforms/GVN/2011-07-07-MatchIntrinsicExtract.ll b/llvm/test/Transforms/GVN/2011-07-07-MatchIntrinsicExtract.ll
index b139e07bbf9a6d..3ee2b54ea5959b 100644
--- a/llvm/test/Transforms/GVN/2011-07-07-MatchIntrinsicExtract.ll
+++ b/llvm/test/Transforms/GVN/2011-07-07-MatchIntrinsicExtract.ll
@@ -1,9 +1,20 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
;
%0 = type { i64, i1 }
define i64 @test1(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: define i64 @test1(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.uadd.with.overflow.i64(i64 [[A]], i64 [[B]])
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
+; CHECK-NEXT: ret i64 [[TMP1]]
+;
entry:
%uadd = tail call %0 @llvm.uadd.with.overflow.i64(i64 %a, i64 %b)
%uadd.0 = extractvalue %0 %uadd, 0
@@ -11,11 +22,18 @@ entry:
ret i64 %add1
}
-; CHECK-LABEL: @test1(
-; CHECK-NOT: add1
-; CHECK: ret
define i64 @test2(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: define i64 @test2(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.usub.with.overflow.i64(i64 [[A]], i64 [[B]])
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
+; CHECK-NEXT: ret i64 [[TMP1]]
+;
entry:
%usub = tail call %0 @llvm.usub.with.overflow.i64(i64 %a, i64 %b)
%usub.0 = extractvalue %0 %usub, 0
@@ -23,11 +41,18 @@ entry:
ret i64 %sub1
}
-; CHECK-LABEL: @test2(
-; CHECK-NOT: sub1
-; CHECK: ret
define i64 @test3(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: define i64 @test3(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.umul.with.overflow.i64(i64 [[A]], i64 [[B]])
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
+; CHECK-NEXT: ret i64 [[TMP1]]
+;
entry:
%umul = tail call %0 @llvm.umul.with.overflow.i64(i64 %a, i64 %b)
%umul.0 = extractvalue %0 %umul, 0
@@ -35,11 +60,18 @@ entry:
ret i64 %mul1
}
-; CHECK-LABEL: @test3(
-; CHECK-NOT: mul1
-; CHECK: ret
define i64 @test4(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: define i64 @test4(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.sadd.with.overflow.i64(i64 [[A]], i64 [[B]])
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
+; CHECK-NEXT: ret i64 [[TMP1]]
+;
entry:
%sadd = tail call %0 @llvm.sadd.with.overflow.i64(i64 %a, i64 %b)
%sadd.0 = extractvalue %0 %sadd, 0
@@ -47,11 +79,18 @@ entry:
ret i64 %add1
}
-; CHECK-LABEL: @test4(
-; CHECK-NOT: add1
-; CHECK: ret
define i64 @test5(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: define i64 @test5(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.ssub.with.overflow.i64(i64 [[A]], i64 [[B]])
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
+; CHECK-NEXT: ret i64 [[TMP1]]
+;
entry:
%ssub = tail call %0 @llvm.ssub.with.overflow.i64(i64 %a, i64 %b)
%ssub.0 = extractvalue %0 %ssub, 0
@@ -59,11 +98,18 @@ entry:
ret i64 %sub1
}
-; CHECK-LABEL: @test5(
-; CHECK-NOT: sub1
-; CHECK: ret
define i64 @test6(i64 %a, i64 %b) nounwind ssp {
+; CHECK-LABEL: define i64 @test6(
+; CHECK-SAME: i64 [[A:%.*]], i64 [[B:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = call { i64, i1 } @llvm.smul.with.overflow.i64(i64 [[A]], i64 [[B]])
+; CHECK-NEXT: [[TMP1:%.*]] = extractvalue { i64, i1 } [[TMP0]], 0
+; CHECK-NEXT: [[TMP2:%.*]] = insertvalue [[TMP0]] poison, i64 [[TMP1]], 0
+; CHECK-NEXT: [[TMP3:%.*]] = extractvalue { i64, i1 } [[TMP0]], 1
+; CHECK-NEXT: [[TMP4:%.*]] = insertvalue [[TMP0]] [[TMP2]], i1 [[TMP3]], 1
+; CHECK-NEXT: ret i64 [[TMP1]]
+;
entry:
%smul = tail call %0 @llvm.smul.with.overflow.i64(i64 %a, i64 %b)
%smul.0 = extractvalue %0 %smul, 0
@@ -71,9 +117,6 @@ entry:
ret i64 %mul1
}
-; CHECK-LABEL: @test6(
-; CHECK-NOT: mul1
-; CHECK: ret
declare void @exit(i32) noreturn
declare %0 @llvm.uadd.with.overflow.i64(i64, i64) nounwind readnone
diff --git a/llvm/test/Transforms/GVN/2011-09-07-TypeIdFor.ll b/llvm/test/Transforms/GVN/2011-09-07-TypeIdFor.ll
index 01cc316433a6ba..a8abd318435138 100644
--- a/llvm/test/Transforms/GVN/2011-09-07-TypeIdFor.ll
+++ b/llvm/test/Transforms/GVN/2011-09-07-TypeIdFor.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
%struct.__fundamental_type_info_pseudo = type { %struct.__type_info_pseudo }
%struct.__type_info_pseudo = type { ptr, ptr }
@@ -18,26 +19,70 @@ declare void @__cxa_end_catch()
declare i32 @__gxx_personality_v0(i32, i64, ptr, ptr)
define void @_Z3foov() uwtable personality ptr @__gxx_personality_v0 {
+; CHECK-LABEL: define void @_Z3foov(
+; CHECK-SAME: ) #[[ATTR1:[0-9]+]] personality ptr @__gxx_personality_v0 {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: invoke void @_Z4barv()
+; CHECK-NEXT: to label %[[RETURN:.*]] unwind label %[[LPAD:.*]]
+; CHECK: [[LPAD]]:
+; CHECK-NEXT: [[TMP0:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT: catch ptr @_ZTIi
+; CHECK-NEXT: catch ptr @_ZTIb
+; CHECK-NEXT: catch ptr @_ZTIi
+; CHECK-NEXT: catch ptr @_ZTIb
+; CHECK-NEXT: [[EXC_PTR2_I:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 0
+; CHECK-NEXT: [[FILTER3_I:%.*]] = extractvalue { ptr, i32 } [[TMP0]], 1
+; CHECK-NEXT: [[TYPEID_I:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIi)
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[FILTER3_I]], [[TYPEID_I]]
+; CHECK-NEXT: br i1 [[TMP1]], label %[[PPAD:.*]], label %[[NEXT:.*]]
+; CHECK: [[NEXT]]:
+; CHECK-NEXT: [[TYPEID1_I:%.*]] = tail call i32 @llvm.eh.typeid.for.p0(ptr @_ZTIb)
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i32 [[FILTER3_I]], [[TYPEID1_I]]
+; CHECK-NEXT: br i1 [[TMP2]], label %[[PPAD2:.*]], label %[[NEXT2:.*]]
+; CHECK: [[PPAD]]:
+; CHECK-NEXT: [[TMP3:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXC_PTR2_I]]) #[[ATTR0:[0-9]+]]
+; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR0]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[PPAD2]]:
+; CHECK-NEXT: [[D_2073_5_I:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXC_PTR2_I]]) #[[ATTR0]]
+; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR0]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[NEXT2]]:
+; CHECK-NEXT: call void @_Z7cleanupv()
+; CHECK-NEXT: br i1 false, label %[[PPAD3:.*]], label %[[NEXT3:.*]]
+; CHECK: [[NEXT3]]:
+; CHECK-NEXT: br i1 false, label %[[PPAD4:.*]], label %[[UNWIND:.*]]
+; CHECK: [[UNWIND]]:
+; CHECK-NEXT: resume { ptr, i32 } [[TMP0]]
+; CHECK: [[PPAD3]]:
+; CHECK-NEXT: [[TMP4:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXC_PTR2_I]]) #[[ATTR0]]
+; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR0]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[PPAD4]]:
+; CHECK-NEXT: [[D_2080_5:%.*]] = tail call ptr @__cxa_begin_catch(ptr [[EXC_PTR2_I]]) #[[ATTR0]]
+; CHECK-NEXT: tail call void @__cxa_end_catch() #[[ATTR0]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
invoke void @_Z4barv()
- to label %return unwind label %lpad
+ to label %return unwind label %lpad
lpad: ; preds = %entry
%0 = landingpad { ptr, i32 }
- catch ptr @_ZTIi
- catch ptr @_ZTIb
- catch ptr @_ZTIi
- catch ptr @_ZTIb
+ catch ptr @_ZTIi
+ catch ptr @_ZTIb
+ catch ptr @_ZTIi
+ catch ptr @_ZTIb
%exc_ptr2.i = extractvalue { ptr, i32 } %0, 0
%filter3.i = extractvalue { ptr, i32 } %0, 1
%typeid.i = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
-; CHECK: call i32 @llvm.eh.typeid.for
%1 = icmp eq i32 %filter3.i, %typeid.i
br i1 %1, label %ppad, label %next
next: ; preds = %lpad
%typeid1.i = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIb)
-; CHECK: call i32 @llvm.eh.typeid.for
%2 = icmp eq i32 %filter3.i, %typeid1.i
br i1 %2, label %ppad2, label %next2
@@ -54,7 +99,6 @@ ppad2: ; preds = %next
next2: ; preds = %next
call void @_Z7cleanupv()
%typeid = tail call i32 @llvm.eh.typeid.for(ptr @_ZTIi)
-; CHECK-NOT: call i32 @llvm.eh.typeid.for
%4 = icmp eq i32 %filter3.i, %typeid
br i1 %4, label %ppad3, label %next3
diff --git a/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather-inseltpoison.ll b/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather-inseltpoison.ll
index c2b123bcb694af..f6df4ca080c854 100644
--- a/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather-inseltpoison.ll
+++ b/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather-inseltpoison.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
declare void @llvm.masked.scatter.v2i32.v2p0(<2 x i32> , <2 x ptr> , i32 , <2 x i1> )
@@ -6,13 +7,27 @@ declare <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr>, i32, <2 x i1>, <2 x
; This test ensures that masked scatter and gather operations, which take vectors of pointers,
; do not have pointer aliasing ignored when being processed.
; No scatter/gather calls should end up eliminated
-; CHECK: llvm.masked.gather
-; CHECK: llvm.masked.gather
-; CHECK: llvm.masked.scatter
-; CHECK: llvm.masked.gather
-; CHECK: llvm.masked.scatter
-; CHECK: llvm.masked.gather
define spir_kernel void @test(<2 x ptr> %in1, <2 x ptr> %in2, ptr %out) {
+; CHECK-LABEL: define spir_kernel void @test(
+; CHECK-SAME: <2 x ptr> [[IN1:%.*]], <2 x ptr> [[IN2:%.*]], ptr [[OUT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP_1:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP_I:%.*]] = insertelement <2 x ptr> poison, ptr [[TMP_0]], i32 0
+; CHECK-NEXT: [[TMP:%.*]] = insertelement <2 x ptr> [[TMP_I]], ptr [[TMP_1]], i32 1
+; CHECK-NEXT: [[IN1_V:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[IN1]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: [[IN2_V:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[IN2]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: call void @llvm.masked.scatter.v2i32.v2p0(<2 x i32> [[IN1_V]], <2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>)
+; CHECK-NEXT: [[TMP_V_0:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: call void @llvm.masked.scatter.v2i32.v2p0(<2 x i32> [[IN2_V]], <2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>)
+; CHECK-NEXT: [[TMP_V_1:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: [[TMP_V_1_0:%.*]] = extractelement <2 x i32> [[TMP_V_1]], i32 0
+; CHECK-NEXT: [[TMP_V_1_1:%.*]] = extractelement <2 x i32> [[TMP_V_1]], i32 1
+; CHECK-NEXT: store i32 [[TMP_V_1_0]], ptr [[OUT]], align 4
+; CHECK-NEXT: [[OUT_1:%.*]] = getelementptr i32, ptr [[OUT]], i32 1
+; CHECK-NEXT: store i32 [[TMP_V_1_1]], ptr [[OUT_1]], align 4
+; CHECK-NEXT: ret void
+;
entry:
; Just some temporary storage
%tmp.0 = alloca i32
diff --git a/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll b/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll
index e18f38835e8330..f4005f18e18245 100644
--- a/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll
+++ b/llvm/test/Transforms/GVN/2016-08-30-MaskedScatterGather.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
declare void @llvm.masked.scatter.v2i32.v2p0(<2 x i32> , <2 x ptr> , i32 , <2 x i1> )
@@ -6,13 +7,27 @@ declare <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr>, i32, <2 x i1>, <2 x
; This test ensures that masked scatter and gather operations, which take vectors of pointers,
; do not have pointer aliasing ignored when being processed.
; No scatter/gather calls should end up eliminated
-; CHECK: llvm.masked.gather
-; CHECK: llvm.masked.gather
-; CHECK: llvm.masked.scatter
-; CHECK: llvm.masked.gather
-; CHECK: llvm.masked.scatter
-; CHECK: llvm.masked.gather
define spir_kernel void @test(<2 x ptr> %in1, <2 x ptr> %in2, ptr %out) {
+; CHECK-LABEL: define spir_kernel void @test(
+; CHECK-SAME: <2 x ptr> [[IN1:%.*]], <2 x ptr> [[IN2:%.*]], ptr [[OUT:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP_0:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP_1:%.*]] = alloca i32, align 4
+; CHECK-NEXT: [[TMP_I:%.*]] = insertelement <2 x ptr> undef, ptr [[TMP_0]], i32 0
+; CHECK-NEXT: [[TMP:%.*]] = insertelement <2 x ptr> [[TMP_I]], ptr [[TMP_1]], i32 1
+; CHECK-NEXT: [[IN1_V:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[IN1]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: [[IN2_V:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[IN2]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: call void @llvm.masked.scatter.v2i32.v2p0(<2 x i32> [[IN1_V]], <2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>)
+; CHECK-NEXT: [[TMP_V_0:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: call void @llvm.masked.scatter.v2i32.v2p0(<2 x i32> [[IN2_V]], <2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>)
+; CHECK-NEXT: [[TMP_V_1:%.*]] = call <2 x i32> @llvm.masked.gather.v2i32.v2p0(<2 x ptr> [[TMP]], i32 1, <2 x i1> <i1 true, i1 true>, <2 x i32> undef)
+; CHECK-NEXT: [[TMP_V_1_0:%.*]] = extractelement <2 x i32> [[TMP_V_1]], i32 0
+; CHECK-NEXT: [[TMP_V_1_1:%.*]] = extractelement <2 x i32> [[TMP_V_1]], i32 1
+; CHECK-NEXT: store i32 [[TMP_V_1_0]], ptr [[OUT]], align 4
+; CHECK-NEXT: [[OUT_1:%.*]] = getelementptr i32, ptr [[OUT]], i32 1
+; CHECK-NEXT: store i32 [[TMP_V_1_1]], ptr [[OUT_1]], align 4
+; CHECK-NEXT: ret void
+;
entry:
; Just some temporary storage
%tmp.0 = alloca i32
diff --git a/llvm/test/Transforms/GVN/assume-equal.ll b/llvm/test/Transforms/GVN/assume-equal.ll
index 2ca8f3384e8133..a27b0e45bf9e18 100644
--- a/llvm/test/Transforms/GVN/assume-equal.ll
+++ b/llvm/test/Transforms/GVN/assume-equal.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
%struct.A = type { ptr }
@@ -7,9 +8,26 @@
; Checks if indirect calls can be replaced with direct
; assuming that %vtable == @_ZTV1A (with alignment).
; Checking const propagation across other BBs
-; CHECK-LABEL: define void @_Z1gb(
define void @_Z1gb(i1 zeroext %p) {
+; CHECK-LABEL: define void @_Z1gb(
+; CHECK-SAME: i1 zeroext [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @_Znwm(i64 8)
+; CHECK-NEXT: tail call void @_ZN1AC1Ev(ptr [[CALL]])
+; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8
+; CHECK-NEXT: [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP_VTABLES]])
+; CHECK-NEXT: br i1 [[P]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: br label %[[IF_END:.*]]
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: [[CALL5:%.*]] = tail call i32 @_ZN1A3barEv(ptr [[CALL]])
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: ret void
+;
entry:
%call = tail call noalias ptr @_Znwm(i64 8) #4
tail call void @_ZN1AC1Ev(ptr %call) #1
@@ -20,18 +38,16 @@ entry:
if.then: ; preds = %entry
%0 = load ptr, ptr %vtable, align 8
-
- ; CHECK: call i32 @_ZN1A3fooEv(
+
%call2 = tail call i32 %0(ptr %call) #1
-
+
br label %if.end
if.else: ; preds = %entry
%vfn47 = getelementptr inbounds ptr, ptr %vtable, i64 1
-
- ; CHECK: call i32 @_ZN1A3barEv(
+
%1 = load ptr, ptr %vfn47, align 8
-
+
%call5 = tail call i32 %1(ptr %call) #1
br label %if.end
@@ -40,8 +56,28 @@ if.end: ; preds = %if.else, %if.then
}
; Check integration with invariant.group handling
-; CHECK-LABEL: define void @invariantGroupHandling(i1 zeroext %p) {
define void @invariantGroupHandling(i1 zeroext %p) {
+; CHECK-LABEL: define void @invariantGroupHandling(
+; CHECK-SAME: i1 zeroext [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @_Znwm(i64 8)
+; CHECK-NEXT: tail call void @_ZN1AC1Ev(ptr [[CALL]])
+; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8, !invariant.group [[META0:![0-9]+]]
+; CHECK-NEXT: [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP_VTABLES]])
+; CHECK-NEXT: br i1 [[P]], label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: [[CALLX:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: [[CALLY:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: [[UNKNOWN:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: br label %[[IF_END:.*]]
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: [[CALL5:%.*]] = tail call i32 @_ZN1A3barEv(ptr [[CALL]])
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: ret void
+;
entry:
%call = tail call noalias ptr @_Znwm(i64 8) #4
tail call void @_ZN1AC1Ev(ptr %call) #1
@@ -52,32 +88,27 @@ entry:
if.then: ; preds = %entry
%0 = load ptr, ptr %vtable, align 8
-
-; CHECK: call i32 @_ZN1A3fooEv(
+
%call2 = tail call i32 %0(ptr %call) #1
%vtable1 = load ptr, ptr %call, align 8, !invariant.group !0
%call1 = load ptr, ptr %vtable1, align 8
-; CHECK: call i32 @_ZN1A3fooEv(
%callx = tail call i32 %call1(ptr %call) #1
-
+
%vtable2 = load ptr, ptr %call, align 8, !invariant.group !0
%call4 = load ptr, ptr %vtable2, align 8
-; CHECK: call i32 @_ZN1A3fooEv(
%cally = tail call i32 %call4(ptr %call) #1
-
+
%vtable3 = load ptr, ptr %call, align 8, !invariant.group !0
%vfun = load ptr, ptr %vtable3, align 8
-; CHECK: call i32 @_ZN1A3fooEv(
%unknown = tail call i32 %vfun(ptr %call) #1
-
+
br label %if.end
if.else: ; preds = %entry
%vfn47 = getelementptr inbounds ptr, ptr %vtable, i64 1
-
- ; CHECK: call i32 @_ZN1A3barEv(
+
%1 = load ptr, ptr %vfn47, align 8
-
+
%call5 = tail call i32 %1(ptr %call) #1
br label %if.end
@@ -87,122 +118,173 @@ if.end: ; preds = %if.else, %if.then
; Checking const propagation in the same BB
-; CHECK-LABEL: define i32 @main()
define i32 @main() {
+; CHECK-LABEL: define i32 @main() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call noalias ptr @_Znwm(i64 8)
+; CHECK-NEXT: tail call void @_ZN1AC1Ev(ptr [[CALL]])
+; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8
+; CHECK-NEXT: [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[CMP_VTABLES]])
+; CHECK-NEXT: [[CALL2:%.*]] = tail call i32 @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: ret i32 0
+;
entry:
- %call = tail call noalias ptr @_Znwm(i64 8)
- tail call void @_ZN1AC1Ev(ptr %call)
+ %call = tail call noalias ptr @_Znwm(i64 8)
+ tail call void @_ZN1AC1Ev(ptr %call)
%vtable = load ptr, ptr %call, align 8
%cmp.vtables = icmp eq ptr %vtable, getelementptr inbounds ([4 x ptr], ptr @_ZTV1A, i64 0, i64 2)
tail call void @llvm.assume(i1 %cmp.vtables)
-
- ; CHECK: call i32 @_ZN1A3fooEv(
+
%0 = load ptr, ptr %vtable, align 8
-
+
%call2 = tail call i32 %0(ptr %call)
ret i32 0
}
; This tests checks const propatation with fcmp instruction.
-; CHECK-LABEL: define float @_Z1gf(float %p)
define float @_Z1gf(float %p) {
+; CHECK-LABEL: define float @_Z1gf(
+; CHECK-SAME: float [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4
+; CHECK-NEXT: [[F:%.*]] = alloca float, align 4
+; CHECK-NEXT: store float [[P]], ptr [[P_ADDR]], align 4
+; CHECK-NEXT: store float 3.000000e+00, ptr [[F]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq float 3.000000e+00, [[P]]
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT: ret float 3.000000e+00
+;
entry:
%p.addr = alloca float, align 4
%f = alloca float, align 4
store float %p, ptr %p.addr, align 4
-
+
store float 3.000000e+00, ptr %f, align 4
%0 = load float, ptr %p.addr, align 4
%1 = load float, ptr %f, align 4
%cmp = fcmp oeq float %1, %0 ; note const on lhs
call void @llvm.assume(i1 %cmp)
-
- ; CHECK: ret float 3.000000e+00
+
ret float %0
}
-; CHECK-LABEL: define float @_Z1hf(float %p)
define float @_Z1hf(float %p) {
+; CHECK-LABEL: define float @_Z1hf(
+; CHECK-SAME: float [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4
+; CHECK-NEXT: store float [[P]], ptr [[P_ADDR]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq float [[P]], 3.000000e+00
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT: ret float 3.000000e+00
+;
entry:
%p.addr = alloca float, align 4
store float %p, ptr %p.addr, align 4
-
+
%0 = load float, ptr %p.addr, align 4
%cmp = fcmp nnan ueq float %0, 3.000000e+00
call void @llvm.assume(i1 %cmp)
-
- ; CHECK: ret float 3.000000e+00
+
ret float %0
}
-; CHECK-LABEL: define float @_Z1if(float %p)
define float @_Z1if(float %p) {
+; CHECK-LABEL: define float @_Z1if(
+; CHECK-SAME: float [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P_ADDR:%.*]] = alloca float, align 4
+; CHECK-NEXT: store float [[P]], ptr [[P_ADDR]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq float [[P]], 3.000000e+00
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT: ret float [[P]]
+;
entry:
%p.addr = alloca float, align 4
store float %p, ptr %p.addr, align 4
-
+
%0 = load float, ptr %p.addr, align 4
%cmp = fcmp ueq float %0, 3.000000e+00 ; no nnan flag - can't propagate
call void @llvm.assume(i1 %cmp)
-
- ; CHECK-NOT: ret float 3.000000e+00
+
ret float %0
}
; This test checks if constant propagation works for multiple node edges
-; CHECK-LABEL: define i32 @_Z1ii(i32 %p)
define i32 @_Z1ii(i32 %p) {
+; CHECK-LABEL: define i32 @_Z1ii(
+; CHECK-SAME: i32 [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P]], 42
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT: br i1 true, label %[[BB2:.*]], label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br i1 true, label %[[BB2]], label %[[BB2]]
+; CHECK: [[BB0:.*:]]
+; CHECK-NEXT: ret i32 42
+;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
-
- ; CHECK: br i1 true, label %bb2, label %bb2
+
br i1 %cmp, label %bb2, label %bb2
bb2:
call void @llvm.assume(i1 true)
- ; CHECK: br i1 true, label %bb2, label %bb2
br i1 %cmp, label %bb2, label %bb2
-
- ; CHECK: ret i32 42
+
ret i32 %p
}
-; CHECK-LABEL: define i32 @_Z1ij(i32 %p)
define i32 @_Z1ij(i32 %p) {
+; CHECK-LABEL: define i32 @_Z1ij(
+; CHECK-SAME: i32 [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P]], 42
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT: br i1 true, label %[[BB2:.*]], label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: br i1 true, label %[[BB2]], label %[[BB2]]
+; CHECK: [[BB0:.*:]]
+; CHECK-NEXT: ret i32 42
+;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
-
- ; CHECK: br i1 true, label %bb2, label %bb2
+
br i1 %cmp, label %bb2, label %bb2
bb2:
- ; CHECK-NOT: %cmp2 =
%cmp2 = icmp eq i32 %p, 42
- ; CHECK-NOT: call void @llvm.assume(
call void @llvm.assume(i1 %cmp2)
-
- ; CHECK: br i1 true, label %bb2, label %bb2
+
br i1 %cmp, label %bb2, label %bb2
-
- ; CHECK: ret i32 42
+
ret i32 %p
}
-; CHECK-LABEL: define i32 @_Z1ik(i32 %p)
define i32 @_Z1ik(i32 %p) {
+; CHECK-LABEL: define i32 @_Z1ik(
+; CHECK-SAME: i32 [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[P]], 42
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP]])
+; CHECK-NEXT: br i1 true, label %[[BB2:.*]], label %[[BB3:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: store i8 poison, ptr null, align 1
+; CHECK-NEXT: ret i32 15
+; CHECK: [[BB3]]:
+; CHECK-NEXT: ret i32 17
+;
entry:
%cmp = icmp eq i32 %p, 42
call void @llvm.assume(i1 %cmp)
-
- ; CHECK: br i1 true, label %bb2, label %bb3
+
br i1 %cmp, label %bb2, label %bb3
bb2:
- ; CHECK-NOT: %cmp3 =
%cmp3 = icmp eq i32 %p, 43
- ; CHECK: store i8 poison, ptr null
call void @llvm.assume(i1 %cmp3)
ret i32 15
bb3:
@@ -210,42 +292,54 @@ bb3:
}
; This test checks if GVN can do the constant propagation correctly
-; when there are multiple uses of the same assume value in the
+; when there are multiple uses of the same assume value in the
; basic block that has a loop back-edge pointing to itself.
;
-; CHECK-LABEL: define i32 @_Z1il(i32 %val, i1 %k)
define i32 @_Z1il(i32 %val, i1 %k) {
+; CHECK-LABEL: define i32 @_Z1il(
+; CHECK-SAME: i32 [[VAL:%.*]], i1 [[K:%.*]]) {
+; CHECK-NEXT: br label %[[NEXT:.*]]
+; CHECK: [[NEXT]]:
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]])
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[VAL]], 50
+; CHECK-NEXT: br i1 [[CMP]], label %[[NEXT]], label %[[MEH:.*]]
+; CHECK: [[MEH]]:
+; CHECK-NEXT: ret i32 0
+;
br label %next
next:
-; CHECK: tail call void @llvm.assume(i1 %k)
-; CHECK-NEXT: %cmp = icmp eq i32 %val, 50
tail call void @llvm.assume(i1 %k)
tail call void @llvm.assume(i1 %k)
%cmp = icmp eq i32 %val, 50
br i1 %cmp, label %next, label %meh
meh:
- ret i32 0
+ ret i32 0
}
; This test checks if GVN can prevent the constant propagation correctly
; in the successor blocks that are not dominated by the basic block
; with the assume instruction.
;
-; CHECK-LABEL: define i1 @_z1im(i32 %val, i1 %k, i1 %j)
define i1 @_z1im(i32 %val, i1 %k, i1 %j) {
+; CHECK-LABEL: define i1 @_z1im(
+; CHECK-SAME: i32 [[VAL:%.*]], i1 [[K:%.*]], i1 [[J:%.*]]) {
+; CHECK-NEXT: br i1 [[J]], label %[[NEXT:.*]], label %[[MEH:.*]]
+; CHECK: [[NEXT]]:
+; CHECK-NEXT: tail call void @llvm.assume(i1 [[K]])
+; CHECK-NEXT: br label %[[MEH]]
+; CHECK: [[MEH]]:
+; CHECK-NEXT: ret i1 [[K]]
+;
br i1 %j, label %next, label %meh
next:
-; CHECK: tail call void @llvm.assume(i1 %k)
-; CHECK-NEXT: br label %meh
tail call void @llvm.assume(i1 %k)
tail call void @llvm.assume(i1 %k)
br label %meh
meh:
-; CHECK: ret i1 %k
ret i1 %k
}
@@ -256,3 +350,6 @@ declare i32 @_ZN1A3fooEv(ptr)
declare i32 @_ZN1A3barEv(ptr)
!0 = !{!"struct A"}
+;.
+; CHECK: [[META0]] = !{!"struct A"}
+;.
diff --git a/llvm/test/Transforms/GVN/basic-undef-test.ll b/llvm/test/Transforms/GVN/basic-undef-test.ll
index d12c3db4bdf0ea..d6e1ffb790cc22 100644
--- a/llvm/test/Transforms/GVN/basic-undef-test.ll
+++ b/llvm/test/Transforms/GVN/basic-undef-test.ll
@@ -1,15 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
; ModuleID = 'test3.ll'
target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
define i32 @main(ptr %foo) {
+; CHECK-LABEL: define i32 @main(
+; CHECK-SAME: ptr [[FOO:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[FOO]], align 4
+; CHECK-NEXT: store i32 5, ptr undef, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[TMP0]], [[TMP0]]
+; CHECK-NEXT: ret i32 [[TMP1]]
+;
entry:
-; CHECK: load i32, ptr %foo, align 4
%0 = load i32, ptr %foo, align 4
store i32 5, ptr undef, align 4
-; CHECK-NOT: load i32, ptr %foo, align 4
%1 = load i32, ptr %foo, align 4
-; CHECK: add i32 %0, %0
%2 = add i32 %0, %1
ret i32 %2
}
diff --git a/llvm/test/Transforms/GVN/basic.ll b/llvm/test/Transforms/GVN/basic.ll
index 09155bf4cf2fd5..d2615611749189 100644
--- a/llvm/test/Transforms/GVN/basic.ll
+++ b/llvm/test/Transforms/GVN/basic.ll
@@ -1,15 +1,16 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
define i32 @main() {
+; CHECK-LABEL: define i32 @main() {
+; CHECK-NEXT: [[BLOCK1:.*:]]
+; CHECK-NEXT: ret i32 0
+;
block1:
- %z1 = bitcast i32 0 to i32
- br label %block2
+ %z1 = bitcast i32 0 to i32
+ br label %block2
block2:
%z2 = bitcast i32 0 to i32
ret i32 %z2
}
-; CHECK: define i32 @main() {
-; CHECK-NEXT: block1:
-; CHECK-NEXT: ret i32 0
-; CHECK-NEXT: }
diff --git a/llvm/test/Transforms/GVN/bitcast-of-call.ll b/llvm/test/Transforms/GVN/bitcast-of-call.ll
index 6c4e8d29899774..c3dd71163e7c62 100644
--- a/llvm/test/Transforms/GVN/bitcast-of-call.ll
+++ b/llvm/test/Transforms/GVN/bitcast-of-call.ll
@@ -1,13 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
; PR2213
define ptr @f(ptr %x) {
+; CHECK-LABEL: define ptr @f(
+; CHECK-SAME: ptr [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP:%.*]] = call ptr @m(i32 12)
+; CHECK-NEXT: ret ptr [[TMP]]
+;
entry:
- %tmp = call ptr @m( i32 12 ) ; <ptr> [#uses=2]
- %tmp1 = bitcast ptr %tmp to ptr ; <ptr> [#uses=0]
- %tmp2 = bitcast ptr %tmp to ptr ; <ptr> [#uses=0]
-; CHECK-NOT: %tmp2
- ret ptr %tmp2
+ %tmp = call ptr @m( i32 12 ) ; <ptr> [#uses=2]
+ %tmp1 = bitcast ptr %tmp to ptr ; <ptr> [#uses=0]
+ %tmp2 = bitcast ptr %tmp to ptr ; <ptr> [#uses=0]
+ ret ptr %tmp2
}
declare ptr @m(i32)
diff --git a/llvm/test/Transforms/GVN/br-identical.ll b/llvm/test/Transforms/GVN/br-identical.ll
index 9997e01abefea2..2bccb96cffe9b9 100644
--- a/llvm/test/Transforms/GVN/br-identical.ll
+++ b/llvm/test/Transforms/GVN/br-identical.ll
@@ -1,8 +1,33 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S -o - %s | FileCheck %s
; If a branch has two identical successors, we cannot declare either dead.
define void @widget(i1 %p) {
+; CHECK-LABEL: define void @widget(
+; CHECK-SAME: i1 [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[BB2:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: [[T1:%.*]] = phi i64 [ 0, %[[ENTRY]] ], [ [[T2:%.*]], %[[BB7:.*]] ]
+; CHECK-NEXT: [[T2]] = add i64 [[T1]], 1
+; CHECK-NEXT: [[T3:%.*]] = icmp ult i64 0, [[T2]]
+; CHECK-NEXT: br i1 [[T3]], label %[[BB3:.*]], label %[[BB4:.*]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: [[T4:%.*]] = call i64 @f()
+; CHECK-NEXT: br label %[[BB4]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: [[FOO:%.*]] = phi i64 [ [[T4]], %[[BB3]] ], [ 0, %[[BB2]] ]
+; CHECK-NEXT: br i1 [[P]], label %[[BB5:.*]], label %[[BB6:.*]]
+; CHECK: [[BB5]]:
+; CHECK-NEXT: br i1 true, label %[[BB7]], label %[[BB7]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: br i1 true, label %[[BB7]], label %[[BB7]]
+; CHECK: [[BB7]]:
+; CHECK-NEXT: br i1 [[P]], label %[[BB2]], label %[[BB8:.*]]
+; CHECK: [[BB8]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %bb2
@@ -17,7 +42,6 @@ bb3:
br label %bb4
bb4:
- ; CHECK-NOT: phi {{.*}} undef
%foo = phi i64 [ %t4, %bb3 ], [ 0, %bb2 ]
br i1 %p, label %bb5, label %bb6
diff --git a/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll b/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
index 726dc214064d26..7928aaf1f47d1c 100644
--- a/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
+++ b/llvm/test/Transforms/GVN/callbr-loadpre-critedge.ll
@@ -10,7 +10,7 @@ define void @widget(ptr %tmp1) {
; CHECK-LABEL: @widget(
; CHECK-NEXT: bb:
; CHECK-NEXT: callbr void asm sideeffect "", "!i,!i"()
-; CHECK-NEXT: to label [[BB4:%.*]] [label [[BB5:%.*]], label %bb.bb8_crit_edge]
+; CHECK-NEXT: to label [[BB4:%.*]] [label [[BB5:%.*]], label %bb.bb8_crit_edge]
; CHECK: bb.bb8_crit_edge:
; CHECK-NEXT: [[TMP10_PRE:%.*]] = load ptr, ptr [[TMP1:%.*]], align 8
; CHECK-NEXT: br label [[BB8:%.*]]
diff --git a/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll b/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
index 9c186f7ea36ade..5fc827c4a76c81 100644
--- a/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
+++ b/llvm/test/Transforms/GVN/callbr-scalarpre-critedge.ll
@@ -9,7 +9,7 @@ define void @wombat(i64 %arg, ptr %arg1, i64 %arg2, ptr %arg3) {
; CHECK-NEXT: bb:
; CHECK-NEXT: [[TMP5:%.*]] = or i64 [[ARG2:%.*]], [[ARG:%.*]]
; CHECK-NEXT: callbr void asm sideeffect "", "!i,!i"()
-; CHECK-NEXT: to label [[BB6:%.*]] [label [[BB7:%.*]], label %bb.bb9_crit_edge]
+; CHECK-NEXT: to label [[BB6:%.*]] [label [[BB7:%.*]], label %bb.bb9_crit_edge]
; CHECK: bb.bb9_crit_edge:
; CHECK-NEXT: [[DOTPRE:%.*]] = trunc i64 [[TMP5]] to i32
; CHECK-NEXT: br label [[BB9:%.*]]
diff --git a/llvm/test/Transforms/GVN/calloc-load-removal.ll b/llvm/test/Transforms/GVN/calloc-load-removal.ll
index 3a21344581d39b..2e222dc30bb5f0 100644
--- a/llvm/test/Transforms/GVN/calloc-load-removal.ll
+++ b/llvm/test/Transforms/GVN/calloc-load-removal.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=gvn < %s | FileCheck %s
; Check that loads from calloc are recognized as being zero.
@@ -5,14 +6,15 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; Function Attrs: nounwind uwtable
define i32 @test1() {
+; CHECK-LABEL: define i32 @test1() {
+; CHECK-NEXT: [[TMP1:%.*]] = tail call noalias ptr @calloc(i64 1, i64 4)
+; CHECK-NEXT: ret i32 0
+;
%1 = tail call noalias ptr @calloc(i64 1, i64 4)
; This load is trivially constant zero
%2 = load i32, ptr %1, align 4
ret i32 %2
-; CHECK-LABEL: @test1(
-; CHECK-NOT: %2 = load i32, ptr %1, align 4
-; CHECK: ret i32 0
; CHECK_NO_LIBCALLS-LABEL: @test1(
; CHECK_NO_LIBCALLS: load
@@ -21,6 +23,18 @@ define i32 @test1() {
}
define i32 @as_invoke(i1 %c) personality ptr undef {
+; CHECK-LABEL: define i32 @as_invoke(
+; CHECK-SAME: i1 [[C:%.*]]) personality ptr undef {
+; CHECK-NEXT: [[BB3:.*:]]
+; CHECK-NEXT: [[MEM:%.*]] = invoke noalias ptr @calloc(i64 1, i64 4)
+; CHECK-NEXT: to label %[[BB4:.*]] unwind label %[[BB1:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: ret i32 0
+; CHECK: [[BB4]]:
+; CHECK-NEXT: ret i32 0
+;
bb3:
%mem = invoke noalias ptr @calloc(i64 1, i64 4)
to label %bb4 unwind label %bb1
@@ -34,9 +48,6 @@ bb4:
%res = load i32, ptr %mem, align 4
ret i32 %res
-; CHECK-LABEL: @as_invoke(
-; CHECK-NOT: %3 = load i32, ptr %2, align 4
-; CHECK: ret i32 0
; CHECK_NO_LIBCALLS-LABEL: @as_invoke(
; CHECK_NO_LIBCALLS: load
diff --git a/llvm/test/Transforms/GVN/calls-nonlocal.ll b/llvm/test/Transforms/GVN/calls-nonlocal.ll
index e8915452d85577..43b31007d95429 100644
--- a/llvm/test/Transforms/GVN/calls-nonlocal.ll
+++ b/llvm/test/Transforms/GVN/calls-nonlocal.ll
@@ -1,75 +1,77 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; Two occurrences of strlen should be zapped.
; RUN: opt < %s -passes=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-darwin9"
define i32 @test(i32 %g, ptr %P) nounwind {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: i32 [[G:%.*]], ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP2:%.*]] = call i32 @strlen(ptr [[P]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: [[TMP3:%.*]] = icmp eq i32 [[TMP2]], 100
+; CHECK-NEXT: [[TMP34:%.*]] = zext i1 [[TMP3]] to i8
+; CHECK-NEXT: br i1 [[TMP3]], label %[[BB:.*]], label %[[BB6:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: br label %[[BB27:.*]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: [[TMP8:%.*]] = add i32 [[G]], 42
+; CHECK-NEXT: br i1 false, label %[[BB14:.*]], label %[[BB16:.*]]
+; CHECK: [[BB14]]:
+; CHECK-NEXT: br label %[[BB27]]
+; CHECK: [[BB16]]:
+; CHECK-NEXT: [[TMP18:%.*]] = mul i32 [[TMP8]], 2
+; CHECK-NEXT: br i1 false, label %[[BB24:.*]], label %[[BB26:.*]]
+; CHECK: [[BB24]]:
+; CHECK-NEXT: br label %[[BB27]]
+; CHECK: [[BB26]]:
+; CHECK-NEXT: br label %[[BB27]]
+; CHECK: [[BB27]]:
+; CHECK-NEXT: [[TMP_0:%.*]] = phi i32 [ 11, %[[BB26]] ], [ poison, %[[BB24]] ], [ poison, %[[BB14]] ], [ [[G]], %[[BB]] ]
+; CHECK-NEXT: ret i32 [[TMP_0]]
+;
entry:
- %tmp2 = call i32 @strlen( ptr %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
+ %tmp2 = call i32 @strlen( ptr %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
+ br label %bb27
bb6: ; preds = %entry
- %tmp8 = add i32 %g, 42 ; <i32> [#uses=2]
- %tmp10 = call i32 @strlen( ptr %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
+ %tmp8 = add i32 %g, 42 ; <i32> [#uses=2]
+ %tmp10 = call i32 @strlen( ptr %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
+ br label %bb27
bb16: ; preds = %bb6
- %tmp18 = mul i32 %tmp8, 2 ; <i32> [#uses=1]
- %tmp20 = call i32 @strlen( ptr %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
+ %tmp18 = mul i32 %tmp8, 2 ; <i32> [#uses=1]
+ %tmp20 = call i32 @strlen( ptr %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
+ br label %bb27
bb26: ; preds = %bb16
- br label %bb27
+ 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
+ %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
+ ret i32 %tmp.0
}
-; CHECK: define i32 @test(i32 %g, ptr %P) #0 {
-; CHECK: entry:
-; CHECK: %tmp2 = call i32 @strlen(ptr %P) #1
-; CHECK: %tmp3 = icmp eq i32 %tmp2, 100
-; CHECK: %tmp34 = zext i1 %tmp3 to i8
-; CHECK: br i1 %tmp3, label %bb, label %bb6
-; CHECK: bb:
-; CHECK: br label %bb27
-; CHECK: bb6:
-; CHECK: %tmp8 = add i32 %g, 42
-; CHECK: br i1 false, label %bb14, label %bb16
-; CHECK: bb14:
-; CHECK: br label %bb27
-; CHECK: bb16:
-; CHECK: %tmp18 = mul i32 %tmp8, 2
-; CHECK: br i1 false, label %bb24, label %bb26
-; CHECK: bb24:
-; CHECK: br label %bb27
-; CHECK: bb26:
-; CHECK: br label %bb27
-; CHECK: bb27:
-; CHECK: %tmp.0 = phi i32 [ 11, %bb26 ], [ poison, %bb24 ], [ poison, %bb14 ], [ %g, %bb ]
-; CHECK: ret i32 %tmp.0
-; CHECK: }
-declare i32 @strlen(ptr) nounwind readonly
+declare i32 @strlen(ptr) nounwind readonly
diff --git a/llvm/test/Transforms/GVN/calls-readonly.ll b/llvm/test/Transforms/GVN/calls-readonly.ll
index b4855e41a64f59..aa51bd87928a80 100644
--- a/llvm/test/Transforms/GVN/calls-readonly.ll
+++ b/llvm/test/Transforms/GVN/calls-readonly.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
; Should delete the second call to strlen even though the intervening strchr call exists.
@@ -5,6 +6,22 @@ target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f3
target triple = "i386-apple-darwin7"
define ptr @test(ptr %P, ptr %Q, i32 %x, i32 %y) nounwind readonly {
+; CHECK-LABEL: define ptr @test(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i32 [[X:%.*]], i32 [[Y:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = tail call i32 @strlen(ptr [[P]]), !prof [[PROF0:![0-9]+]]
+; CHECK-NEXT: [[TMP1:%.*]] = icmp eq i32 [[TMP0]], 0
+; CHECK-NEXT: br i1 [[TMP1]], label %[[BB:.*]], label %[[BB1:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[TMP2:%.*]] = sdiv i32 [[X]], [[Y]]
+; CHECK-NEXT: br label %[[BB1]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[X_ADDR_0:%.*]] = phi i32 [ [[TMP2]], %[[BB]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: [[TMP3:%.*]] = tail call ptr @strchr(ptr [[Q]], i32 97)
+; CHECK-NEXT: [[TMP4:%.*]] = add i32 [[X_ADDR_0]], [[TMP0]]
+; CHECK-NEXT: [[TMP5:%.*]] = getelementptr i8, ptr [[TMP3]], i32 [[X_ADDR_0]]
+; CHECK-NEXT: ret ptr [[TMP5]]
+;
entry:
%0 = tail call i32 @strlen(ptr %P), !prof !0 ; <i32> [#uses=2]
%1 = icmp eq i32 %0, 0 ; <i1> [#uses=1]
@@ -24,21 +41,6 @@ bb1: ; preds = %bb, %entry
ret ptr %6
}
-; CHECK: define ptr @test(ptr %P, ptr %Q, i32 %x, i32 %y) #0 {
-; CHECK: entry:
-; CHECK-NEXT: %0 = tail call i32 @strlen(ptr %P), !prof !0
-; CHECK-NEXT: %1 = icmp eq i32 %0, 0
-; CHECK-NEXT: br i1 %1, label %bb, label %bb1
-; CHECK: bb:
-; CHECK-NEXT: %2 = sdiv i32 %x, %y
-; CHECK-NEXT: br label %bb1
-; CHECK: bb1:
-; CHECK-NEXT: %x_addr.0 = phi i32 [ %2, %bb ], [ %x, %entry ]
-; CHECK-NEXT: %3 = tail call ptr @strchr(ptr %Q, i32 97)
-; CHECK-NEXT: %4 = add i32 %x_addr.0, %0
-; CHECK-NEXT: %5 = getelementptr i8, ptr %3, i32 %x_addr.0
-; CHECK-NEXT: ret ptr %5
-; CHECK: }
declare i32 @strlen(ptr) nounwind readonly
@@ -46,3 +48,6 @@ declare ptr @strchr(ptr, i32) nounwind readonly
!0 = !{!"branch_weights", i32 95}
!1 = !{!"branch_weights", i32 95}
+;.
+; CHECK: [[PROF0]] = !{!"branch_weights", i32 95}
+;.
diff --git a/llvm/test/Transforms/GVN/cond_br.ll b/llvm/test/Transforms/GVN/cond_br.ll
index 19166d17a83204..91609286da855d 100644
--- a/llvm/test/Transforms/GVN/cond_br.ll
+++ b/llvm/test/Transforms/GVN/cond_br.ll
@@ -1,12 +1,24 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
@y = external global i32
@z = external global i32
; Function Attrs: nounwind ssp uwtable
define void @foo(i32 %x) {
-; CHECK: @foo(i32 %x)
-; CHECK: %.pre = load i32, ptr @y
-; CHECK: call void @bar(i32 %.pre)
+; CHECK-LABEL: define void @foo(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, ptr @y, align 4
+; CHECK-NEXT: br i1 false, label %[[IF_THEN:.*]], label %[[ENTRY_IF_END_CRIT_EDGE:.*]]
+; CHECK: [[ENTRY_IF_END_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[IF_END:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X]], 3
+; CHECK-NEXT: store i32 [[ADD]], ptr @y, align 4
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: tail call void @bar(i32 [[DOTPRE]])
+; CHECK-NEXT: ret void
+;
%t = sub i32 %x, %x
%.pre = load i32, ptr @y, align 4
@@ -28,9 +40,22 @@ if.end: ; preds = %entry.if.end_crit_e
}
define void @foo2(i32 %x) {
-; CHECK: @foo2(i32 %x)
-; CHECK: %.pre = load i32, ptr @y
-; CHECK: tail call void @bar(i32 %.pre)
+; CHECK-LABEL: define void @foo2(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, ptr @y, align 4
+; CHECK-NEXT: br i1 false, label %[[IF_THEN:.*]], label %[[IF_ELSE:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[X]], 3
+; CHECK-NEXT: store i32 [[ADD]], ptr @y, align 4
+; CHECK-NEXT: br label %[[IF_END:.*]]
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: store i32 1, ptr @z, align 4
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: tail call void @bar(i32 [[DOTPRE]])
+; CHECK-NEXT: ret void
+;
entry:
%t = sub i32 %x, %x
%.pre = load i32, ptr @y, align 4
diff --git a/llvm/test/Transforms/GVN/cond_br2.ll b/llvm/test/Transforms/GVN/cond_br2.ll
index 420246713882e9..69216f0cb41d63 100644
--- a/llvm/test/Transforms/GVN/cond_br2.ll
+++ b/llvm/test/Transforms/GVN/cond_br2.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %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-S128"
@@ -10,10 +11,77 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; Function Attrs: ssp uwtable
define void @_Z4testv() #0 personality ptr @__gxx_personality_v0 {
-; CHECK: @_Z4testv()
-; CHECK: invoke.cont:
-; CHECK: br i1 true, label %new.notnull.i11, label %if.end.i14
-; CHECK: Retry.i10:
+; CHECK-LABEL: define void @_Z4testv(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] personality ptr @__gxx_personality_v0 {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[SV:%.*]] = alloca %"class.llvm::SmallVector", align 16
+; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 64, ptr [[SV]]) #[[ATTR4:[0-9]+]]
+; CHECK-NEXT: [[FIRSTEL_I_I_I_I_I_I:%.*]] = getelementptr inbounds %"class.llvm::SmallVector", ptr [[SV]], i64 0, i32 0, i32 0, i32 0, i32 0, i32 3
+; CHECK-NEXT: store ptr [[FIRSTEL_I_I_I_I_I_I]], ptr [[SV]], align 16, !tbaa [[TBAA0:![0-9]+]]
+; CHECK-NEXT: [[ENDX_I_I_I_I_I_I:%.*]] = getelementptr inbounds %"class.llvm::SmallVector", ptr [[SV]], i64 0, i32 0, i32 0, i32 0, i32 0, i32 1
+; CHECK-NEXT: store ptr [[FIRSTEL_I_I_I_I_I_I]], ptr [[ENDX_I_I_I_I_I_I]], align 8, !tbaa [[TBAA0]]
+; CHECK-NEXT: [[CAPACITYX_I_I_I_I_I_I:%.*]] = getelementptr inbounds %"class.llvm::SmallVector", ptr [[SV]], i64 0, i32 0, i32 0, i32 0, i32 0, i32 2
+; CHECK-NEXT: [[ADD_PTR_I_I_I_I2_I_I:%.*]] = getelementptr inbounds %"union.llvm::SmallVectorBase::U", ptr [[FIRSTEL_I_I_I_I_I_I]], i64 2
+; CHECK-NEXT: store ptr [[ADD_PTR_I_I_I_I2_I_I]], ptr [[CAPACITYX_I_I_I_I_I_I]], align 16, !tbaa [[TBAA0]]
+; CHECK-NEXT: br i1 true, label %[[RETRY_I:.*]], label %[[IF_END_I:.*]]
+; CHECK: [[RETRY_I]]:
+; CHECK-NEXT: br i1 false, label %[[RETRY_I_INVOKE_CONT_CRIT_EDGE:.*]], label %[[NEW_NOTNULL_I:.*]]
+; CHECK: [[RETRY_I_INVOKE_CONT_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[INVOKE_CONT:.*]]
+; CHECK: [[NEW_NOTNULL_I]]:
+; CHECK-NEXT: store i32 1, ptr [[FIRSTEL_I_I_I_I_I_I]], align 4, !tbaa [[TBAA4:![0-9]+]]
+; CHECK-NEXT: br label %[[INVOKE_CONT]]
+; CHECK: [[IF_END_I]]:
+; CHECK-NEXT: invoke void @_ZN4llvm15SmallVectorBase8grow_podEmm(ptr [[SV]], i64 0, i64 4)
+; CHECK-NEXT: to [[DOTNOEXC:label %.*]] unwind label %[[LPAD:.*]]
+; CHECK: [[_NOEXC:.*:]]
+; CHECK-NEXT: [[DOTPRE_I:%.*]] = load ptr, ptr [[ENDX_I_I_I_I_I_I]], align 8, !tbaa [[TBAA0]]
+; CHECK-NEXT: br label %[[RETRY_I]]
+; CHECK: [[INVOKE_CONT]]:
+; CHECK-NEXT: [[ADD_PTR_I:%.*]] = getelementptr inbounds i8, ptr [[FIRSTEL_I_I_I_I_I_I]], i64 4
+; CHECK-NEXT: store ptr [[ADD_PTR_I]], ptr [[ENDX_I_I_I_I_I_I]], align 8, !tbaa [[TBAA0]]
+; CHECK-NEXT: br i1 true, label %[[NEW_NOTNULL_I11:.*]], label %[[IF_END_I14:.*]]
+; CHECK: [[RETRY_I10:.*]]:
+; CHECK-NEXT: [[DOTPRE_I13:%.*]] = load ptr, ptr [[ENDX_I_I_I_I_I_I]], align 8, !tbaa [[TBAA0]]
+; CHECK-NEXT: [[NEW_ISNULL_I9:%.*]] = icmp eq ptr [[DOTPRE_I13]], null
+; CHECK-NEXT: br i1 [[NEW_ISNULL_I9]], label %[[RETRY_I10_INVOKE_CONT2_CRIT_EDGE:.*]], label %[[RETRY_I10_NEW_NOTNULL_I11_CRIT_EDGE:.*]]
+; CHECK: [[RETRY_I10_NEW_NOTNULL_I11_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[NEW_NOTNULL_I11]]
+; CHECK: [[RETRY_I10_INVOKE_CONT2_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[INVOKE_CONT2:.*]]
+; CHECK: [[NEW_NOTNULL_I11]]:
+; CHECK-NEXT: store i32 2, ptr [[ADD_PTR_I]], align 4, !tbaa [[TBAA4]]
+; CHECK-NEXT: br label %[[INVOKE_CONT2]]
+; CHECK: [[IF_END_I14]]:
+; CHECK-NEXT: invoke void @_ZN4llvm15SmallVectorBase8grow_podEmm(ptr [[SV]], i64 0, i64 4)
+; CHECK-NEXT: to label %[[RETRY_I10]] unwind label %[[LPAD]]
+; CHECK: [[INVOKE_CONT2]]:
+; CHECK-NEXT: [[ADD_PTR_I12:%.*]] = getelementptr inbounds i8, ptr [[ADD_PTR_I]], i64 4
+; CHECK-NEXT: store ptr [[ADD_PTR_I12]], ptr [[ENDX_I_I_I_I_I_I]], align 8, !tbaa [[TBAA0]]
+; CHECK-NEXT: invoke void @_Z1gRN4llvm11SmallVectorIiLj8EEE(ptr [[SV]])
+; CHECK-NEXT: to label %[[INVOKE_CONT3:.*]] unwind label %[[LPAD]]
+; CHECK: [[INVOKE_CONT3]]:
+; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[SV]], align 16, !tbaa [[TBAA0]]
+; CHECK-NEXT: [[CMP_I_I_I_I19:%.*]] = icmp eq ptr [[TMP0]], [[FIRSTEL_I_I_I_I_I_I]]
+; CHECK-NEXT: br i1 [[CMP_I_I_I_I19]], label %[[_ZN4LLVM11SMALLVECTORIILJ8EED1EV_EXIT21:.*]], label %[[IF_THEN_I_I_I20:.*]]
+; CHECK: [[IF_THEN_I_I_I20]]:
+; CHECK-NEXT: call void @free(ptr [[TMP0]]) #[[ATTR4]]
+; CHECK-NEXT: br label %[[_ZN4LLVM11SMALLVECTORIILJ8EED1EV_EXIT21]]
+; CHECK: [[_ZN4LLVM11SMALLVECTORIILJ8EED1EV_EXIT21]]:
+; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 64, ptr [[SV]]) #[[ATTR4]]
+; CHECK-NEXT: ret void
+; CHECK: [[LPAD]]:
+; CHECK-NEXT: [[TMP1:%.*]] = landingpad { ptr, i32 }
+; CHECK-NEXT: cleanup
+; CHECK-NEXT: [[TMP2:%.*]] = load ptr, ptr [[SV]], align 16, !tbaa [[TBAA0]]
+; CHECK-NEXT: [[CMP_I_I_I_I:%.*]] = icmp eq ptr [[TMP2]], [[FIRSTEL_I_I_I_I_I_I]]
+; CHECK-NEXT: br i1 [[CMP_I_I_I_I]], label %[[EH_RESUME:.*]], label %[[IF_THEN_I_I_I:.*]]
+; CHECK: [[IF_THEN_I_I_I]]:
+; CHECK-NEXT: call void @free(ptr [[TMP2]]) #[[ATTR4]]
+; CHECK-NEXT: br label %[[EH_RESUME]]
+; CHECK: [[EH_RESUME]]:
+; CHECK-NEXT: resume { ptr, i32 } [[TMP1]]
+;
entry:
%sv = alloca %"class.llvm::SmallVector", align 16
@@ -42,7 +110,7 @@ new.notnull.i: ; preds = %Retry.i
if.end.i: ; preds = %entry
invoke void @_ZN4llvm15SmallVectorBase8grow_podEmm(ptr %sv, i64 0, i64 4)
- to label %.noexc unwind label %lpad
+ to label %.noexc unwind label %lpad
.noexc: ; preds = %if.end.i
%.pre.i = load ptr, ptr %EndX.i, align 8, !tbaa !4
@@ -67,14 +135,14 @@ new.notnull.i11: ; preds = %invoke.cont, %Retry
if.end.i14: ; preds = %invoke.cont
invoke void @_ZN4llvm15SmallVectorBase8grow_podEmm(ptr %sv, i64 0, i64 4)
- to label %Retry.i10 unwind label %lpad
+ to label %Retry.i10 unwind label %lpad
invoke.cont2: ; preds = %new.notnull.i11, %Retry.i10
%4 = phi ptr [ null, %Retry.i10 ], [ %3, %new.notnull.i11 ]
%add.ptr.i12 = getelementptr inbounds i8, ptr %4, i64 4
store ptr %add.ptr.i12, ptr %EndX.i, align 8, !tbaa !4
invoke void @_Z1gRN4llvm11SmallVectorIiLj8EEE(ptr %sv)
- to label %invoke.cont3 unwind label %lpad
+ to label %invoke.cont3 unwind label %lpad
invoke.cont3: ; preds = %invoke.cont2
%5 = load ptr, ptr %sv, align 16, !tbaa !4
@@ -91,7 +159,7 @@ _ZN4llvm11SmallVectorIiLj8EED1Ev.exit21: ; preds = %invoke.cont3, %if.t
lpad: ; preds = %if.end.i14, %if.end.i, %invoke.cont2
%6 = landingpad { ptr, i32 }
- cleanup
+ cleanup
%7 = load ptr, ptr %sv, align 16, !tbaa !4
%cmp.i.i.i.i = icmp eq ptr %7, %FirstEl.i.i.i.i.i.i
br i1 %cmp.i.i.i.i, label %eh.resume, label %if.then.i.i.i
@@ -130,3 +198,11 @@ attributes #3 = { nounwind "less-precise-fpmad"="false" "frame-pointer"="all" "n
!3 = !{!"int", !1}
!4 = !{!0, !0, i64 0}
!5 = !{!3, !3, i64 0}
+;.
+; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
+; CHECK: [[META1]] = !{!"any pointer", [[META2:![0-9]+]]}
+; CHECK: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]]}
+; CHECK: [[META3]] = !{!"Simple C/C++ TBAA"}
+; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
+; CHECK: [[META5]] = !{!"int", [[META2]]}
+;.
diff --git a/llvm/test/Transforms/GVN/dbg-redundant-load.ll b/llvm/test/Transforms/GVN/dbg-redundant-load.ll
index 1ba4e8b73dcac9..8df9617813d2d3 100644
--- a/llvm/test/Transforms/GVN/dbg-redundant-load.ll
+++ b/llvm/test/Transforms/GVN/dbg-redundant-load.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
; Check that the redundant load from %if.then is removed.
@@ -6,15 +7,22 @@
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
-; CHECK: @test_redundant_load(
-; CHECK-LABEL: entry:
-; CHECK-NEXT: load i32, ptr %Y, align 4, !dbg ![[LOC:[0-9]+]]
-; CHECK-LABEL: if.then:
-; CHECK-NOT: load
-; CHECK-LABEL: if.end:
-; CHECK: ![[LOC]] = !DILocation(line: 3, scope: !{{.*}})
define i32 @test_redundant_load(i32 %X, ptr %Y) !dbg !6 {
+; CHECK-LABEL: define i32 @test_redundant_load(
+; CHECK-SAME: i32 [[X:%.*]], ptr [[Y:%.*]]) !dbg [[DBG6:![0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[Y]], align 4, !dbg [[DBG8:![0-9]+]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[X]], -1, !dbg [[DBG9:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[IF_THEN:.*]], label %[[IF_END:.*]], !dbg [[DBG9]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i32 [[TMP0]], [[TMP0]], !dbg [[DBG10:![0-9]+]]
+; CHECK-NEXT: call void @foo(), !dbg [[DBG11:![0-9]+]]
+; CHECK-NEXT: br label %[[IF_END]], !dbg [[DBG12:![0-9]+]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: [[RESULT_0:%.*]] = phi i32 [ [[ADD]], %[[IF_THEN]] ], [ [[TMP0]], %[[ENTRY]] ]
+; CHECK-NEXT: ret i32 [[RESULT_0]], !dbg [[DBG13:![0-9]+]]
+;
entry:
%0 = load i32, ptr %Y, align 4, !dbg !8
%cmp = icmp sgt i32 %X, -1, !dbg !9
@@ -50,3 +58,16 @@ declare void @foo()
!11 = !DILocation(line: 7, scope: !6)
!12 = !DILocation(line: 8, scope: !6)
!13 = !DILocation(line: 10, scope: !6)
+;.
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C_plus_plus, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: LineTablesOnly, enums: [[META2:![0-9]+]])
+; CHECK: [[META1]] = !DIFile(filename: "test.cpp", directory: "")
+; CHECK: [[META2]] = !{}
+; CHECK: [[DBG6]] = distinct !DISubprogram(name: "test_redundant_load", scope: [[META1]], file: [[META1]], line: 2, type: [[META7:![0-9]+]], scopeLine: 2, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META0]], retainedNodes: [[META2]])
+; CHECK: [[META7]] = !DISubroutineType(types: [[META2]])
+; CHECK: [[DBG8]] = !DILocation(line: 3, scope: [[DBG6]])
+; CHECK: [[DBG9]] = !DILocation(line: 5, scope: [[DBG6]])
+; CHECK: [[DBG10]] = !DILocation(line: 6, scope: [[DBG6]])
+; CHECK: [[DBG11]] = !DILocation(line: 7, scope: [[DBG6]])
+; CHECK: [[DBG12]] = !DILocation(line: 8, scope: [[DBG6]])
+; CHECK: [[DBG13]] = !DILocation(line: 10, scope: [[DBG6]])
+;.
diff --git a/llvm/test/Transforms/GVN/debugloc.ll b/llvm/test/Transforms/GVN/debugloc.ll
index 0a50d3e9252e3f..d9cfc49d41d0c9 100644
--- a/llvm/test/Transforms/GVN/debugloc.ll
+++ b/llvm/test/Transforms/GVN/debugloc.ll
@@ -1,10 +1,5 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
-; CHECK: {{^}}for.body:
-; CHECK-NEXT: [[VREG1:%[^ ]+]] = phi{{.*}}[[VREG2:%[^ ]+]],{{.*}}%.sink,
-; CHECK-NOT: !dbg
-; CHECK-SAME: {{$}}
-; CHECK: {{^}}for.inc:
-; CHECK-NEXT: [[VREG2]] = phi{{.*}}%inc,{{.*}}[[VREG1]]
target triple = "x86_64-unknown-linux-gnu"
@@ -12,6 +7,35 @@ target triple = "x86_64-unknown-linux-gnu"
; Function Attrs: nounwind uwtable
define void @foo(i32 %x, i32 %y, i32 %z) local_unnamed_addr #0 !dbg !4 {
+; CHECK-LABEL: define void @foo(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]], i32 [[Z:%.*]]) local_unnamed_addr !dbg [[DBG4:![0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[NOT_TOBOOL:%.*]] = icmp eq i32 [[X]], 0, !dbg [[DBG8:![0-9]+]]
+; CHECK-NEXT: [[DOTSINK:%.*]] = zext i1 [[NOT_TOBOOL]] to i32, !dbg [[DBG8]]
+; CHECK-NEXT: store i32 [[DOTSINK]], ptr @g, align 4, !tbaa [[TBAA9:![0-9]+]]
+; CHECK-NEXT: [[CMP8:%.*]] = icmp sgt i32 [[Y]], 0, !dbg [[DBG13:![0-9]+]]
+; CHECK-NEXT: br i1 [[CMP8]], label %[[FOR_BODY_PREHEADER:.*]], label %[[FOR_END:.*]], !dbg [[DBG17:![0-9]+]]
+; CHECK: [[FOR_BODY_PREHEADER]]:
+; CHECK-NEXT: br label %[[FOR_BODY:.*]], !dbg [[DBG19:![0-9]+]]
+; CHECK: [[FOR_BODY]]:
+; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[TMP1:%.*]], %[[FOR_INC:.*]] ], [ [[DOTSINK]], %[[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[I_09:%.*]] = phi i32 [ [[INC4:%.*]], %[[FOR_INC]] ], [ 0, %[[FOR_BODY_PREHEADER]] ]
+; CHECK-NEXT: [[CMP1:%.*]] = icmp sgt i32 [[I_09]], [[Z]], !dbg [[DBG19]]
+; CHECK-NEXT: br i1 [[CMP1]], label %[[IF_THEN2:.*]], label %[[FOR_INC]], !dbg [[DBG21:![0-9]+]]
+; CHECK: [[IF_THEN2]]:
+; CHECK-NEXT: [[INC:%.*]] = add nsw i32 [[TMP0]], 1, !dbg [[DBG22:![0-9]+]]
+; CHECK-NEXT: store i32 [[INC]], ptr @g, align 4, !dbg [[DBG22]], !tbaa [[TBAA9]]
+; CHECK-NEXT: br label %[[FOR_INC]], !dbg [[DBG23:![0-9]+]]
+; CHECK: [[FOR_INC]]:
+; CHECK-NEXT: [[TMP1]] = phi i32 [ [[INC]], %[[IF_THEN2]] ], [ [[TMP0]], %[[FOR_BODY]] ]
+; CHECK-NEXT: [[INC4]] = add nuw nsw i32 [[I_09]], 1, !dbg [[DBG24:![0-9]+]]
+; CHECK-NEXT: [[EXITCOND:%.*]] = icmp ne i32 [[INC4]], [[Y]], !dbg [[DBG13]]
+; CHECK-NEXT: br i1 [[EXITCOND]], label %[[FOR_BODY]], label %[[FOR_END_LOOPEXIT:.*]], !dbg [[DBG17]]
+; CHECK: [[FOR_END_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[FOR_END]], !dbg [[DBG26:![0-9]+]]
+; CHECK: [[FOR_END]]:
+; CHECK-NEXT: ret void, !dbg [[DBG26]]
+;
entry:
%not.tobool = icmp eq i32 %x, 0, !dbg !8
%.sink = zext i1 %not.tobool to i32, !dbg !8
@@ -75,3 +99,30 @@ for.end: ; preds = %for.end.loopexit, %
!llvm.dbg.cu = !{!0}
!llvm.module.flags = !{!2, !3}
+;.
+; CHECK: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META1:![0-9]+]], isOptimized: false, runtimeVersion: 0, emissionKind: NoDebug)
+; CHECK: [[META1]] = !DIFile(filename: "foo.c", directory: {{.*}})
+; CHECK: [[DBG4]] = distinct !DISubprogram(name: "foo", scope: [[META1]], file: [[META1]], line: 3, type: [[META5:![0-9]+]], scopeLine: 3, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]])
+; CHECK: [[META5]] = !DISubroutineType(types: [[META6:![0-9]+]])
+; CHECK: [[META6]] = !{null, [[META7:![0-9]+]], [[META7]], [[META7]]}
+; CHECK: [[META7]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed)
+; CHECK: [[DBG8]] = !DILocation(line: 4, column: 7, scope: [[DBG4]])
+; CHECK: [[TBAA9]] = !{[[META10:![0-9]+]], [[META10]], i64 0}
+; CHECK: [[META10]] = !{!"int", [[META11:![0-9]+]], i64 0}
+; CHECK: [[META11]] = !{!"omnipotent char", [[META12:![0-9]+]], i64 0}
+; CHECK: [[META12]] = !{!"Simple C/C++ TBAA"}
+; CHECK: [[DBG13]] = !DILocation(line: 10, column: 13, scope: [[META14:![0-9]+]])
+; CHECK: [[META14]] = !DILexicalBlockFile(scope: [[META15:![0-9]+]], file: [[META1]], discriminator: 1)
+; CHECK: [[META15]] = distinct !DILexicalBlock(scope: [[META16:![0-9]+]], file: [[META1]], line: 10, column: 3)
+; CHECK: [[META16]] = distinct !DILexicalBlock(scope: [[DBG4]], file: [[META1]], line: 10, column: 3)
+; CHECK: [[DBG17]] = !DILocation(line: 10, column: 3, scope: [[META18:![0-9]+]])
+; CHECK: [[META18]] = !DILexicalBlockFile(scope: [[META16]], file: [[META1]], discriminator: 1)
+; CHECK: [[DBG19]] = !DILocation(line: 11, column: 11, scope: [[META20:![0-9]+]])
+; CHECK: [[META20]] = distinct !DILexicalBlock(scope: [[META15]], file: [[META1]], line: 11, column: 9)
+; CHECK: [[DBG21]] = !DILocation(line: 11, column: 9, scope: [[META15]])
+; CHECK: [[DBG22]] = !DILocation(line: 12, column: 8, scope: [[META20]])
+; CHECK: [[DBG23]] = !DILocation(line: 12, column: 7, scope: [[META20]])
+; CHECK: [[DBG24]] = !DILocation(line: 10, column: 20, scope: [[META25:![0-9]+]])
+; CHECK: [[META25]] = !DILexicalBlockFile(scope: [[META15]], file: [[META1]], discriminator: 2)
+; CHECK: [[DBG26]] = !DILocation(line: 13, column: 1, scope: [[DBG4]])
+;.
diff --git a/llvm/test/Transforms/GVN/edge.ll b/llvm/test/Transforms/GVN/edge.ll
index 94a25b94707bab..45a928a05fbf60 100644
--- a/llvm/test/Transforms/GVN/edge.ll
+++ b/llvm/test/Transforms/GVN/edge.ll
@@ -1,7 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
define i32 @f1(i32 %x) {
- ; CHECK-LABEL: define i32 @f1(
+; CHECK-LABEL: define i32 @f1(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[BB0:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp eq i32 [[X]], 0
+; CHECK-NEXT: br i1 [[CMP]], label %[[BB2:.*]], label %[[BB1:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: ret i32 [[X]]
+;
bb0:
%cmp = icmp eq i32 %x, 0
br i1 %cmp, label %bb2, label %bb1
@@ -11,12 +21,19 @@ bb2:
%cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
%foo = add i32 %cond, %x
ret i32 %foo
- ; CHECK: bb2:
- ; CHECK: ret i32 %x
}
define i32 @f2(i32 %x) {
- ; CHECK-LABEL: define i32 @f2(
+; CHECK-LABEL: define i32 @f2(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[BB0:.*:]]
+; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[X]], 0
+; CHECK-NEXT: br i1 [[CMP]], label %[[BB1:.*]], label %[[BB2:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: ret i32 [[X]]
+;
bb0:
%cmp = icmp ne i32 %x, 0
br i1 %cmp, label %bb1, label %bb2
@@ -26,12 +43,20 @@ bb2:
%cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
%foo = add i32 %cond, %x
ret i32 %foo
- ; CHECK: bb2:
- ; CHECK: ret i32 %x
}
define i32 @f3(i32 %x) {
- ; CHECK-LABEL: define i32 @f3(
+; CHECK-LABEL: define i32 @f3(
+; CHECK-SAME: i32 [[X:%.*]]) {
+; CHECK-NEXT: [[BB0:.*:]]
+; CHECK-NEXT: switch i32 [[X]], label %[[BB1:.*]] [
+; CHECK-NEXT: i32 0, label %[[BB2:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: ret i32 [[X]]
+;
bb0:
switch i32 %x, label %bb1 [ i32 0, label %bb2]
bb1:
@@ -40,13 +65,21 @@ bb2:
%cond = phi i32 [ %x, %bb0 ], [ 0, %bb1 ]
%foo = add i32 %cond, %x
ret i32 %foo
- ; CHECK: bb2:
- ; CHECK: ret i32 %x
}
declare void @g(i1)
define void @f4(ptr %x) {
; CHECK-LABEL: define void @f4(
+; CHECK-SAME: ptr [[X:%.*]]) {
+; CHECK-NEXT: [[BB0:.*:]]
+; CHECK-NEXT: [[Y:%.*]] = icmp eq ptr null, [[X]]
+; CHECK-NEXT: br i1 [[Y]], label %[[BB2:.*]], label %[[BB1:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: br label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: call void @g(i1 [[Y]])
+; CHECK-NEXT: ret void
+;
bb0:
%y = icmp eq ptr null, %x
br i1 %y, label %bb2, label %bb1
@@ -55,11 +88,22 @@ bb1:
bb2:
%zed = icmp eq ptr null, %x
call void @g(i1 %zed)
-; CHECK: call void @g(i1 %y)
ret void
}
define double @fcmp_oeq_not_zero(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_oeq_not_zero(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 2.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]
+; CHECK: [[IF]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp oeq double %y, 2.0
br i1 %cmp, label %if, label %return
@@ -72,11 +116,21 @@ return:
%retval = phi double [ %div, %if ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_oeq_not_zero(
-; CHECK: %div = fdiv double %x, 2.0
}
define double @fcmp_une_not_zero(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_une_not_zero(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], 2.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp une double %y, 2.0
br i1 %cmp, label %return, label %else
@@ -89,11 +143,21 @@ return:
%retval = phi double [ %div, %else ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_une_not_zero(
-; CHECK: %div = fdiv double %x, 2.0
}
define double @fcmp_one_possibly_nan(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_one_possibly_nan(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp one double [[Y]], 2.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp one double %y, 2.0
br i1 %cmp, label %return, label %else
@@ -106,11 +170,21 @@ return:
%retval = phi double [ %div, %else ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_one_possibly_nan(
-; CHECK: %div = fdiv double %x, %y
}
define double @fcmp_one_not_zero_or_nan(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_one_not_zero_or_nan(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan one double [[Y]], 2.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp nnan one double %y, 2.0
br i1 %cmp, label %return, label %else
@@ -123,14 +197,24 @@ return:
%retval = phi double [ %div, %else ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_one_not_zero_or_nan(
-; CHECK: %div = fdiv double %x, 2.0
}
-; PR22376 - We can't propagate zero constants because -0.0
+; PR22376 - We can't propagate zero constants because -0.0
; compares equal to 0.0. If %y is -0.0 in this test case,
; we would produce the wrong sign on the infinity return value.
define double @fcmp_oeq_zero(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_oeq_zero(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], 0.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]
+; CHECK: [[IF]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp oeq double %y, 0.0
br i1 %cmp, label %if, label %return
@@ -143,11 +227,21 @@ return:
%retval = phi double [ %div, %if ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_oeq_zero(
-; CHECK: %div = fdiv double %x, %y
}
define double @fcmp_une_zero(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_une_zero(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], -0.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp une double %y, -0.0
br i1 %cmp, label %return, label %else
@@ -160,51 +254,83 @@ return:
%retval = phi double [ %div, %else ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_une_zero(
-; CHECK: %div = fdiv double %x, %y
}
; We also cannot propagate a value if it's not a constant.
; This is because the value could be 0.0 or -0.0.
define double @fcmp_oeq_maybe_zero(double %x, double %y, double %z1, double %z2) {
+; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1]], [[Z2]]
+; CHECK-NEXT: [[CMP:%.*]] = fcmp oeq double [[Y]], [[Z]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[IF:.*]], label %[[RETURN:.*]]
+; CHECK: [[IF]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Z]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[IF]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
- %z = fadd double %z1, %z2
- %cmp = fcmp oeq double %y, %z
- br i1 %cmp, label %if, label %return
+ %z = fadd double %z1, %z2
+ %cmp = fcmp oeq double %y, %z
+ br i1 %cmp, label %if, label %return
if:
- %div = fdiv double %x, %z
- br label %return
+ %div = fdiv double %x, %z
+ br label %return
return:
- %retval = phi double [ %div, %if ], [ %x, %entry ]
- ret double %retval
+ %retval = phi double [ %div, %if ], [ %x, %entry ]
+ ret double %retval
-; CHECK-LABEL: define double @fcmp_oeq_maybe_zero(
-; CHECK: %div = fdiv double %x, %z
}
define double @fcmp_une_maybe_zero(double %x, double %y, double %z1, double %z2) {
+; CHECK-LABEL: define double @fcmp_une_maybe_zero(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]], double [[Z1:%.*]], double [[Z2:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[Z:%.*]] = fadd double [[Z1]], [[Z2]]
+; CHECK-NEXT: [[CMP:%.*]] = fcmp une double [[Y]], [[Z]]
+; CHECK-NEXT: br i1 [[CMP]], label %[[RETURN:.*]], label %[[ELSE:.*]]
+; CHECK: [[ELSE]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Z]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[ELSE]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
- %z = fadd double %z1, %z2
- %cmp = fcmp une double %y, %z
- br i1 %cmp, label %return, label %else
+ %z = fadd double %z1, %z2
+ %cmp = fcmp une double %y, %z
+ br i1 %cmp, label %return, label %else
else:
- %div = fdiv double %x, %z
- br label %return
+ %div = fdiv double %x, %z
+ br label %return
return:
- %retval = phi double [ %div, %else ], [ %x, %entry ]
- ret double %retval
+ %retval = phi double [ %div, %else ], [ %x, %entry ]
+ ret double %retval
-; CHECK-LABEL: define double @fcmp_une_maybe_zero(
-; CHECK: %div = fdiv double %x, %z
}
define double @fcmp_ueq_possibly_nan(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_ueq_possibly_nan(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp ueq double [[Y]], 2.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[DO_DIV:.*]], label %[[RETURN:.*]]
+; CHECK: [[DO_DIV]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], [[Y]]
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[DO_DIV]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp ueq double %y, 2.0
br i1 %cmp, label %do_div, label %return
@@ -217,11 +343,21 @@ return:
%retval = phi double [ %div, %do_div ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_ueq_possibly_nan(
-; CHECK: %div = fdiv double %x, %y
}
define double @fcmp_ueq_not_zero_or_nan(double %x, double %y) {
+; CHECK-LABEL: define double @fcmp_ueq_not_zero_or_nan(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[CMP:%.*]] = fcmp nnan ueq double [[Y]], 2.000000e+00
+; CHECK-NEXT: br i1 [[CMP]], label %[[DO_DIV:.*]], label %[[RETURN:.*]]
+; CHECK: [[DO_DIV]]:
+; CHECK-NEXT: [[DIV:%.*]] = fdiv double [[X]], 2.000000e+00
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[RETVAL:%.*]] = phi double [ [[DIV]], %[[DO_DIV]] ], [ [[X]], %[[ENTRY]] ]
+; CHECK-NEXT: ret double [[RETVAL]]
+;
entry:
%cmp = fcmp nnan ueq double %y, 2.0
br i1 %cmp, label %do_div, label %return
@@ -234,6 +370,4 @@ return:
%retval = phi double [ %div, %do_div ], [ %x, %entry ]
ret double %retval
-; CHECK-LABEL: define double @fcmp_ueq_not_zero_or_nan(
-; CHECK: %div = fdiv double %x, 2.0
}
diff --git a/llvm/test/Transforms/GVN/fake-use-constprop.ll b/llvm/test/Transforms/GVN/fake-use-constprop.ll
index 1466f9f9fca277..6633b6f26350d6 100644
--- a/llvm/test/Transforms/GVN/fake-use-constprop.ll
+++ b/llvm/test/Transforms/GVN/fake-use-constprop.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
;
; The Global Value Numbering pass (GVN) propagates boolean values
@@ -33,11 +34,20 @@
;; GVN should propagate a constant value through to a regular call, but not to
;; a fake use, which should continue to track the original value.
-; CHECK: %[[CONV_VAR:[a-zA-Z0-9]+]] = fptosi
-; CHECK: call {{.+}} @bees(i8 0)
-; CHECK: call {{.+}} @llvm.fake.use(i8 %[[CONV_VAR]])
define i32 @foo(float %f) optdebug {
+; CHECK-LABEL: define i32 @foo(
+; CHECK-SAME: float [[F:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[CONV:%.*]] = fptosi float [[F]] to i8
+; CHECK-NEXT: [[TOBOOL3:%.*]] = icmp eq i8 [[CONV]], 0
+; CHECK-NEXT: br i1 [[TOBOOL3]], label %[[IF_END:.*]], label %[[LAB:.*]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: tail call void (...) @bees(i8 0)
+; CHECK-NEXT: tail call void (...) @llvm.fake.use(i8 [[CONV]])
+; CHECK-NEXT: br label %[[LAB]]
+; CHECK: [[LAB]]:
+; CHECK-NEXT: ret i32 1
+;
%conv = fptosi float %f to i8
%tobool3 = icmp eq i8 %conv, 0
br i1 %tobool3, label %if.end, label %lab
diff --git a/llvm/test/Transforms/GVN/flags.ll b/llvm/test/Transforms/GVN/flags.ll
index 2e5aeedfc19a1c..3f480cb90f959b 100644
--- a/llvm/test/Transforms/GVN/flags.ll
+++ b/llvm/test/Transforms/GVN/flags.ll
@@ -1,8 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
declare void @use(i1)
define void @test1(float %x, float %y) {
+; CHECK-LABEL: define void @test1(
+; CHECK-SAME: float [[X:%.*]], float [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CMP1:%.*]] = fcmp oeq float [[Y]], [[X]]
+; CHECK-NEXT: call void @use(i1 [[CMP1]])
+; CHECK-NEXT: call void @use(i1 [[CMP1]])
+; CHECK-NEXT: ret void
+;
entry:
%cmp1 = fcmp nnan oeq float %y, %x
%cmp2 = fcmp oeq float %x, %y
@@ -11,8 +20,3 @@ entry:
ret void
}
-; CHECK-LABEL: define void @test1(
-; CHECK: %[[cmp:.*]] = fcmp oeq float %y, %x
-; CHECK-NEXT: call void @use(i1 %[[cmp]])
-; CHECK-NEXT: call void @use(i1 %[[cmp]])
-; CHECK-NEXT: ret void
diff --git a/llvm/test/Transforms/GVN/fold-const-expr.ll b/llvm/test/Transforms/GVN/fold-const-expr.ll
index 9e1129eb5bd225..facba13bb40955 100644
--- a/llvm/test/Transforms/GVN/fold-const-expr.ll
+++ b/llvm/test/Transforms/GVN/fold-const-expr.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; GVN failed to do constant expression folding and expanded
; them unfolded in many places, producing exponentially large const
; expressions. As a result, the compilation never fisished.
@@ -7,6 +8,16 @@
%2 = type { i32, i32, i32, i32, i32 }
define i32 @_Z16vector3util_mainv(i32 %x, i32 %y) {
+; CHECK-LABEL: define i32 @_Z16vector3util_mainv(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = alloca [[TMP0:%.*]], align 4
+; CHECK-NEXT: [[TMP114:%.*]] = getelementptr inbounds [[TMP0]], ptr [[TMP1]], i64 0, i32 1
+; CHECK-NEXT: store <4 x i32> <i32 234567891, i32 345678912, i32 456789123, i32 0>, ptr [[TMP114]], align 4
+; CHECK-NEXT: store i32 310393545, ptr [[TMP114]], align 4
+; CHECK-NEXT: store i32 -383584258, ptr [[TMP114]], align 4
+; CHECK-NEXT: store i32 -57163022, ptr [[TMP114]], align 4
+; CHECK-NEXT: ret i32 0
+;
%tmp1 = alloca %2, align 4
%tmp114 = getelementptr inbounds %2, ptr %tmp1, i64 0, i32 1
store <4 x i32> <i32 234567891, i32 345678912, i32 456789123, i32 0>, ptr %tmp114, align 4
@@ -37,7 +48,6 @@ define i32 @_Z16vector3util_mainv(i32 %x, i32 %y) {
%tmp1739 = shl i32 %tmp1738, 22
%tmp1740 = xor i32 %tmp1739, %tmp1738
store i32 %tmp1740, ptr %tmp1683, align 4
-; CHECK: store i32 310393545, ptr %tmp114, align 4
%tmp1756 = getelementptr inbounds %2, ptr %tmp1, i64 0, i32 1
%tmp1761 = load i32, ptr %tmp1756, align 4
%tmp1766 = shl i32 %tmp1761, 5
@@ -65,7 +75,6 @@ define i32 @_Z16vector3util_mainv(i32 %x, i32 %y) {
%tmp1812 = shl i32 %tmp1811, 22
%tmp1813 = xor i32 %tmp1812, %tmp1811
store i32 %tmp1813, ptr %tmp1756, align 4
-; CHECK: store i32 -383584258, ptr %tmp114, align 4
%tmp2645 = getelementptr inbounds %2, ptr %tmp1, i64 0, i32 1
%tmp2650 = load i32, ptr %tmp2645, align 4
%tmp2655 = shl i32 %tmp2650, 5
@@ -93,6 +102,5 @@ define i32 @_Z16vector3util_mainv(i32 %x, i32 %y) {
%tmp2701 = shl i32 %tmp2700, 22
%tmp2702 = xor i32 %tmp2701, %tmp2700
store i32 %tmp2702, ptr %tmp2645, align 4
-; CHECK: store i32 -57163022, ptr %tmp114, align 4
ret i32 0
}
diff --git a/llvm/test/Transforms/GVN/fpmath.ll b/llvm/test/Transforms/GVN/fpmath.ll
index 970dd897e8bfa2..cff579d99c3d91 100644
--- a/llvm/test/Transforms/GVN/fpmath.ll
+++ b/llvm/test/Transforms/GVN/fpmath.ll
@@ -1,10 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
define double @test1(double %x, double %y) {
-; CHECK: @test1(double %x, double %y)
-; CHECK: %add1 = fadd double %x, %y
-; CHECK-NOT: fpmath
-; CHECK: %foo = fadd double %add1, %add1
+; CHECK-LABEL: define double @test1(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = fadd double [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = fadd double [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret double [[FOO]]
+;
%add1 = fadd double %x, %y, !fpmath !0
%add2 = fadd double %x, %y
%foo = fadd double %add1, %add2
@@ -12,9 +15,12 @@ define double @test1(double %x, double %y) {
}
define double @test2(double %x, double %y) {
-; CHECK: @test2(double %x, double %y)
-; CHECK: %add1 = fadd double %x, %y, !fpmath !0
-; CHECK: %foo = fadd double %add1, %add1
+; CHECK-LABEL: define double @test2(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = fadd double [[X]], [[Y]], !fpmath [[META0:![0-9]+]]
+; CHECK-NEXT: [[FOO:%.*]] = fadd double [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret double [[FOO]]
+;
%add1 = fadd double %x, %y, !fpmath !0
%add2 = fadd double %x, %y, !fpmath !0
%foo = fadd double %add1, %add2
@@ -22,9 +28,12 @@ define double @test2(double %x, double %y) {
}
define double @test3(double %x, double %y) {
-; CHECK: @test3(double %x, double %y)
-; CHECK: %add1 = fadd double %x, %y, !fpmath !1
-; CHECK: %foo = fadd double %add1, %add1
+; CHECK-LABEL: define double @test3(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = fadd double [[X]], [[Y]], !fpmath [[META1:![0-9]+]]
+; CHECK-NEXT: [[FOO:%.*]] = fadd double [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret double [[FOO]]
+;
%add1 = fadd double %x, %y, !fpmath !1
%add2 = fadd double %x, %y, !fpmath !0
%foo = fadd double %add1, %add2
@@ -32,9 +41,12 @@ define double @test3(double %x, double %y) {
}
define double @test4(double %x, double %y) {
-; CHECK: @test4(double %x, double %y)
-; CHECK: %add1 = fadd double %x, %y, !fpmath !1
-; CHECK: %foo = fadd double %add1, %add1
+; CHECK-LABEL: define double @test4(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = fadd double [[X]], [[Y]], !fpmath [[META1]]
+; CHECK-NEXT: [[FOO:%.*]] = fadd double [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret double [[FOO]]
+;
%add1 = fadd double %x, %y, !fpmath !0
%add2 = fadd double %x, %y, !fpmath !1
%foo = fadd double %add1, %add2
@@ -42,9 +54,12 @@ define double @test4(double %x, double %y) {
}
define double @test5(double %x, double %y) {
-; CHECK: @test5(double %x, double %y)
-; CHECK: %neg1 = fneg double %x, !fpmath !1
-; CHECK: %foo = fadd double %neg1, %neg1
+; CHECK-LABEL: define double @test5(
+; CHECK-SAME: double [[X:%.*]], double [[Y:%.*]]) {
+; CHECK-NEXT: [[NEG1:%.*]] = fneg double [[X]], !fpmath [[META1]]
+; CHECK-NEXT: [[FOO:%.*]] = fadd double [[NEG1]], [[NEG1]]
+; CHECK-NEXT: ret double [[FOO]]
+;
%neg1 = fneg double %x, !fpmath !0
%neg2 = fneg double %x, !fpmath !1
%foo = fadd double %neg1, %neg2
@@ -53,3 +68,7 @@ define double @test5(double %x, double %y) {
!0 = !{ float 5.0 }
!1 = !{ float 2.5 }
+;.
+; CHECK: [[META0]] = !{float 5.000000e+00}
+; CHECK: [[META1]] = !{float 2.500000e+00}
+;.
diff --git a/llvm/test/Transforms/GVN/funclet.ll b/llvm/test/Transforms/GVN/funclet.ll
index 8ef4c969eadc66..0156f94d9324c2 100644
--- a/llvm/test/Transforms/GVN/funclet.ll
+++ b/llvm/test/Transforms/GVN/funclet.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
target datalayout = "e-m:x-p:32:32-i64:64-f80:32-n8:16:32-a:0:32-S32"
target triple = "i686-pc-windows-msvc"
@@ -8,13 +9,35 @@ target triple = "i686-pc-windows-msvc"
@"_TI1?AUA@@" = external constant %eh.ThrowInfo
define i8 @f() personality ptr @__CxxFrameHandler3 {
+; CHECK-LABEL: define i8 @f() personality ptr @__CxxFrameHandler3 {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[B:%.*]] = alloca i8, align 1
+; CHECK-NEXT: [[C:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[B]], align 1
+; CHECK-NEXT: store i8 13, ptr [[C]], align 1
+; CHECK-NEXT: invoke void @_CxxThrowException(ptr [[B]], ptr nonnull @"_TI1?AUA@@")
+; CHECK-NEXT: to label %[[UNREACHABLE:.*]] unwind label %[[CATCH_DISPATCH:.*]]
+; CHECK: [[CATCH_DISPATCH]]:
+; CHECK-NEXT: [[CS1:%.*]] = catchswitch within none [label %catch] unwind to caller
+; CHECK: [[CATCH:.*:]]
+; CHECK-NEXT: [[CATCHPAD:%.*]] = catchpad within [[CS1]] [ptr null, i32 64, ptr null]
+; CHECK-NEXT: store i8 5, ptr [[B]], align 1
+; CHECK-NEXT: catchret from [[CATCHPAD]] to label %[[TRY_CONT:.*]]
+; CHECK: [[TRY_CONT]]:
+; CHECK-NEXT: [[LOAD_B:%.*]] = load i8, ptr [[B]], align 1
+; CHECK-NEXT: [[LOAD_C:%.*]] = load i8, ptr [[C]], align 1
+; CHECK-NEXT: [[ADD:%.*]] = add i8 [[LOAD_B]], [[LOAD_C]]
+; CHECK-NEXT: ret i8 [[ADD]]
+; CHECK: [[UNREACHABLE]]:
+; CHECK-NEXT: unreachable
+;
entry:
%b = alloca i8
%c = alloca i8
store i8 42, ptr %b
store i8 13, ptr %c
invoke void @_CxxThrowException(ptr %b, ptr nonnull @"_TI1?AUA@@")
- to label %unreachable unwind label %catch.dispatch
+ to label %unreachable unwind label %catch.dispatch
catch.dispatch: ; preds = %entry
%cs1 = catchswitch within none [label %catch] unwind to caller
@@ -33,11 +56,6 @@ try.cont: ; preds = %catch
unreachable: ; preds = %entry
unreachable
}
-; CHECK-LABEL: define i8 @f(
-; CHECK: %[[load_b:.*]] = load i8, ptr %b
-; CHECK-NEXT: %[[load_c:.*]] = load i8, ptr %c
-; CHECK-NEXT: %[[add:.*]] = add i8 %[[load_b]], %[[load_c]]
-; CHECK-NEXT: ret i8 %[[add]]
declare i32 @__CxxFrameHandler3(...)
diff --git a/llvm/test/Transforms/GVN/int_sideeffect.ll b/llvm/test/Transforms/GVN/int_sideeffect.ll
index 513533af38c4e2..3902f6949c964e 100644
--- a/llvm/test/Transforms/GVN/int_sideeffect.ll
+++ b/llvm/test/Transforms/GVN/int_sideeffect.ll
@@ -1,38 +1,56 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S < %s -passes=gvn | FileCheck %s
declare void @llvm.sideeffect()
; Store-to-load forwarding across a @llvm.sideeffect.
-
-; CHECK-LABEL: s2l
-; CHECK-NOT: load
define float @s2l(ptr %p) {
- store float 0.0, ptr %p
- call void @llvm.sideeffect()
- %t = load float, ptr %p
- ret float %t
+; CHECK-LABEL: define float @s2l(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: store float 0.000000e+00, ptr [[P]], align 4
+; CHECK-NEXT: call void @llvm.sideeffect()
+; CHECK-NEXT: ret float 0.000000e+00
+;
+ store float 0.0, ptr %p
+ call void @llvm.sideeffect()
+ %t = load float, ptr %p
+ ret float %t
}
; Redundant load elimination across a @llvm.sideeffect.
-
-; CHECK-LABEL: rle
-; CHECK: load
-; CHECK-NOT: load
define float @rle(ptr %p) {
- %r = load float, ptr %p
- call void @llvm.sideeffect()
- %s = load float, ptr %p
- %t = fadd float %r, %s
- ret float %t
+; CHECK-LABEL: define float @rle(
+; CHECK-SAME: ptr [[P:%.*]]) {
+; CHECK-NEXT: [[R:%.*]] = load float, ptr [[P]], align 4
+; CHECK-NEXT: call void @llvm.sideeffect()
+; CHECK-NEXT: [[T:%.*]] = fadd float [[R]], [[R]]
+; CHECK-NEXT: ret float [[T]]
+;
+ %r = load float, ptr %p
+ call void @llvm.sideeffect()
+ %s = load float, ptr %p
+ %t = fadd float %r, %s
+ ret float %t
}
; LICM across a @llvm.sideeffect.
-
-; CHECK-LABEL: licm
-; CHECK: load
-; CHECK: loop:
-; CHECK-NOT: load
define float @licm(i64 %n, ptr nocapture readonly %p) #0 {
+; CHECK-LABEL: define float @licm(
+; CHECK-SAME: i64 [[N:%.*]], ptr nocapture readonly [[P:%.*]]) {
+; CHECK-NEXT: [[BB0:.*]]:
+; CHECK-NEXT: [[T3_PRE:%.*]] = load float, ptr [[P]], align 4
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[I:%.*]] = phi i64 [ 0, %[[BB0]] ], [ [[T5:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[SUM:%.*]] = phi float [ 0.000000e+00, %[[BB0]] ], [ [[T4:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: call void @llvm.sideeffect()
+; CHECK-NEXT: [[T4]] = fadd float [[SUM]], [[T3_PRE]]
+; CHECK-NEXT: [[T5]] = add i64 [[I]], 1
+; CHECK-NEXT: [[T6:%.*]] = icmp ult i64 [[T5]], [[N]]
+; CHECK-NEXT: br i1 [[T6]], label %[[LOOP]], label %[[BB2:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: ret float [[T4]]
+;
bb0:
br label %loop
diff --git a/llvm/test/Transforms/GVN/invariant.group.ll b/llvm/test/Transforms/GVN/invariant.group.ll
index 9c673ba1ced42d..a8446859264d93 100644
--- a/llvm/test/Transforms/GVN/invariant.group.ll
+++ b/llvm/test/Transforms/GVN/invariant.group.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
%struct.A = type { ptr }
@@ -6,130 +7,174 @@
@unknownPtr = external global i8
-; CHECK-LABEL: define i8 @simple() {
define i8 @simple() {
+; CHECK-LABEL: define i8 @simple() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0:![0-9]+]]
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: ret i8 42
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- call void @foo(ptr %ptr)
-
- %a = load i8, ptr %ptr, !invariant.group !0
- %b = load i8, ptr %ptr, !invariant.group !0
- %c = load i8, ptr %ptr, !invariant.group !0
-; CHECK: ret i8 42
- ret i8 %a
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ call void @foo(ptr %ptr)
+
+ %a = load i8, ptr %ptr, !invariant.group !0
+ %b = load i8, ptr %ptr, !invariant.group !0
+ %c = load i8, ptr %ptr, !invariant.group !0
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @optimizable1() {
define i8 @optimizable1() {
+; CHECK-LABEL: define i8 @optimizable1() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: [[PTR2:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[PTR]])
+; CHECK-NEXT: call void @foo(ptr [[PTR2]])
+; CHECK-NEXT: ret i8 42
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
- %a = load i8, ptr %ptr, !invariant.group !0
-
- call void @foo(ptr %ptr2); call to use %ptr2
-; CHECK: ret i8 42
- ret i8 %a
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
+ %a = load i8, ptr %ptr, !invariant.group !0
+
+ call void @foo(ptr %ptr2); call to use %ptr2
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @optimizable2() {
define i8 @optimizable2() {
+; CHECK-LABEL: define i8 @optimizable2() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: store i8 13, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @bar(i8 13)
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: ret i8 42
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- call void @foo(ptr %ptr)
-
- store i8 13, ptr %ptr ; can't use this store with invariant.group
- %a = load i8, ptr %ptr
- call void @bar(i8 %a) ; call to use %a
-
- call void @foo(ptr %ptr)
- %b = load i8, ptr %ptr, !invariant.group !0
-
-; CHECK: ret i8 42
- ret i8 %b
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ call void @foo(ptr %ptr)
+
+ store i8 13, ptr %ptr ; can't use this store with invariant.group
+ %a = load i8, ptr %ptr
+ call void @bar(i8 %a) ; call to use %a
+
+ call void @foo(ptr %ptr)
+ %b = load i8, ptr %ptr, !invariant.group !0
+
+ ret i8 %b
}
-; CHECK-LABEL: define i1 @proveEqualityForStrip(
define i1 @proveEqualityForStrip(ptr %a) {
; FIXME: The first call could be also removed by GVN. Right now
; DCE removes it. The second call is CSE'd with the first one.
-; CHECK: %b1 = call ptr @llvm.strip.invariant.group.p0(ptr %a)
+; CHECK-LABEL: define i1 @proveEqualityForStrip(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[B1:%.*]] = call ptr @llvm.strip.invariant.group.p0(ptr [[A]])
+; CHECK-NEXT: ret i1 true
+;
%b1 = call ptr @llvm.strip.invariant.group.p0(ptr %a)
-; CHECK-NOT: llvm.strip.invariant.group
%b2 = call ptr @llvm.strip.invariant.group.p0(ptr %a)
%r = icmp eq ptr %b1, %b2
-; CHECK: ret i1 true
ret i1 %r
}
-; CHECK-LABEL: define i8 @unoptimizable1() {
define i8 @unoptimizable1() {
+; CHECK-LABEL: define i8 @unoptimizable1() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[A:%.*]] = load i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: ret i8 [[A]]
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr
- call void @foo(ptr %ptr)
- %a = load i8, ptr %ptr, !invariant.group !0
-; CHECK: ret i8 %a
- ret i8 %a
+ %ptr = alloca i8
+ store i8 42, ptr %ptr
+ call void @foo(ptr %ptr)
+ %a = load i8, ptr %ptr, !invariant.group !0
+ ret i8 %a
}
-; CHECK-LABEL: define void @indirectLoads() {
define void @indirectLoads() {
+; CHECK-LABEL: define void @indirectLoads() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[A:%.*]] = alloca ptr, align 8
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @getPointer(ptr null)
+; CHECK-NEXT: call void @_ZN1AC1Ev(ptr [[CALL]])
+; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8, !invariant.group [[META0]]
+; CHECK-NEXT: [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2)
+; CHECK-NEXT: call void @llvm.assume(i1 [[CMP_VTABLES]])
+; CHECK-NEXT: store ptr [[CALL]], ptr [[A]], align 8
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr [[CALL]])
+; CHECK-NEXT: ret void
+;
entry:
%a = alloca ptr, align 8
-
- %call = call ptr @getPointer(ptr null)
+
+ %call = call ptr @getPointer(ptr null)
call void @_ZN1AC1Ev(ptr %call)
-
-; CHECK: %vtable = load {{.*}} !invariant.group
+
%vtable = load ptr, ptr %call, align 8, !invariant.group !0
%cmp.vtables = icmp eq ptr %vtable, getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2)
call void @llvm.assume(i1 %cmp.vtables)
-
+
store ptr %call, ptr %a, align 8
%0 = load ptr, ptr %a, align 8
-; CHECK: call void @_ZN1A3fooEv(
%vtable1 = load ptr, ptr %0, align 8, !invariant.group !0
%1 = load ptr, ptr %vtable1, align 8
call void %1(ptr %0)
%2 = load ptr, ptr %a, align 8
-; CHECK: call void @_ZN1A3fooEv(
%vtable2 = load ptr, ptr %2, align 8, !invariant.group !0
%3 = load ptr, ptr %vtable2, align 8
-
+
call void %3(ptr %2)
%4 = load ptr, ptr %a, align 8
-
+
%vtable4 = load ptr, ptr %4, align 8, !invariant.group !0
%5 = load ptr, ptr %vtable4, align 8
-; CHECK: call void @_ZN1A3fooEv(
call void %5(ptr %4)
-
+
%vtable5 = load ptr, ptr %call, align 8, !invariant.group !0
%6 = load ptr, ptr %vtable5, align 8
-; CHECK: call void @_ZN1A3fooEv(
call void %6(ptr %4)
-
+
ret void
}
-; CHECK-LABEL: define void @combiningBitCastWithLoad() {
define void @combiningBitCastWithLoad() {
+; CHECK-LABEL: define void @combiningBitCastWithLoad() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[A:%.*]] = alloca ptr, align 8
+; CHECK-NEXT: [[CALL:%.*]] = call ptr @getPointer(ptr null)
+; CHECK-NEXT: call void @_ZN1AC1Ev(ptr [[CALL]])
+; CHECK-NEXT: [[VTABLE:%.*]] = load ptr, ptr [[CALL]], align 8, !invariant.group [[META0]]
+; CHECK-NEXT: [[CMP_VTABLES:%.*]] = icmp eq ptr [[VTABLE]], getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2)
+; CHECK-NEXT: store ptr [[CALL]], ptr [[A]], align 8
+; CHECK-NEXT: [[TMP0:%.*]] = load ptr, ptr [[VTABLE]], align 8
+; CHECK-NEXT: call void [[TMP0]](ptr [[CALL]])
+; CHECK-NEXT: ret void
+;
entry:
%a = alloca ptr, align 8
-
- %call = call ptr @getPointer(ptr null)
+
+ %call = call ptr @getPointer(ptr null)
call void @_ZN1AC1Ev(ptr %call)
-
-; CHECK: %vtable = load {{.*}} !invariant.group
+
%vtable = load ptr, ptr %call, align 8, !invariant.group !0
%cmp.vtables = icmp eq ptr %vtable, getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2)
-
+
store ptr %call, ptr %a, align 8
-; CHECK-NOT: !invariant.group
%0 = load ptr, ptr %a, align 8
%vtable1 = load ptr, ptr %0, align 8, !invariant.group !0
@@ -139,185 +184,255 @@ entry:
ret void
}
-; CHECK-LABEL:define void @loadCombine() {
define void @loadCombine() {
+; CHECK-LABEL: define void @loadCombine() {
+; CHECK-NEXT: [[ENTER:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[A:%.*]] = load i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[A]])
+; CHECK-NEXT: call void @bar(i8 [[A]])
+; CHECK-NEXT: ret void
+;
enter:
%ptr = alloca i8
store i8 42, ptr %ptr
call void @foo(ptr %ptr)
-; CHECK: %[[A:.*]] = load i8, ptr %ptr, align 1, !invariant.group
%a = load i8, ptr %ptr, !invariant.group !0
-; CHECK-NOT: load
%b = load i8, ptr %ptr, !invariant.group !0
-; CHECK: call void @bar(i8 %[[A]])
call void @bar(i8 %a)
-; CHECK: call void @bar(i8 %[[A]])
call void @bar(i8 %b)
ret void
}
-; CHECK-LABEL: define void @loadCombine1() {
define void @loadCombine1() {
+; CHECK-LABEL: define void @loadCombine1() {
+; CHECK-NEXT: [[ENTER:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[C:%.*]] = load i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[C]])
+; CHECK-NEXT: call void @bar(i8 [[C]])
+; CHECK-NEXT: ret void
+;
enter:
%ptr = alloca i8
store i8 42, ptr %ptr
call void @foo(ptr %ptr)
-; CHECK: %[[D:.*]] = load i8, ptr %ptr, align 1, !invariant.group
%c = load i8, ptr %ptr
-; CHECK-NOT: load
%d = load i8, ptr %ptr, !invariant.group !0
-; CHECK: call void @bar(i8 %[[D]])
call void @bar(i8 %c)
-; CHECK: call void @bar(i8 %[[D]])
call void @bar(i8 %d)
ret void
}
-; CHECK-LABEL: define void @loadCombine2() {
define void @loadCombine2() {
+; CHECK-LABEL: define void @loadCombine2() {
+; CHECK-NEXT: [[ENTER:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[E:%.*]] = load i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[E]])
+; CHECK-NEXT: call void @bar(i8 [[E]])
+; CHECK-NEXT: ret void
+;
enter:
%ptr = alloca i8
store i8 42, ptr %ptr
call void @foo(ptr %ptr)
-; CHECK: %[[E:.*]] = load i8, ptr %ptr, align 1, !invariant.group
%e = load i8, ptr %ptr, !invariant.group !0
-; CHECK-NOT: load
%f = load i8, ptr %ptr
-; CHECK: call void @bar(i8 %[[E]])
call void @bar(i8 %e)
-; CHECK: call void @bar(i8 %[[E]])
call void @bar(i8 %f)
ret void
}
-; CHECK-LABEL: define void @loadCombine3() {
define void @loadCombine3() {
+; CHECK-LABEL: define void @loadCombine3() {
+; CHECK-NEXT: [[ENTER:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[E:%.*]] = load i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[E]])
+; CHECK-NEXT: call void @bar(i8 [[E]])
+; CHECK-NEXT: ret void
+;
enter:
%ptr = alloca i8
store i8 42, ptr %ptr
call void @foo(ptr %ptr)
-; CHECK: %[[E:.*]] = load i8, ptr %ptr, align 1, !invariant.group
%e = load i8, ptr %ptr, !invariant.group !0
-; CHECK-NOT: load
%f = load i8, ptr %ptr, !invariant.group !0
-; CHECK: call void @bar(i8 %[[E]])
call void @bar(i8 %e)
-; CHECK: call void @bar(i8 %[[E]])
call void @bar(i8 %f)
ret void
}
-; CHECK-LABEL: define i8 @unoptimizable2() {
define i8 @unoptimizable2() {
+; CHECK-LABEL: define i8 @unoptimizable2() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[A:%.*]] = load i8, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: ret i8 [[A]]
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr
- call void @foo(ptr %ptr)
- %a = load i8, ptr %ptr
- call void @foo(ptr %ptr)
- %b = load i8, ptr %ptr, !invariant.group !0
-
-; CHECK: ret i8 %a
- ret i8 %a
+ %ptr = alloca i8
+ store i8 42, ptr %ptr
+ call void @foo(ptr %ptr)
+ %a = load i8, ptr %ptr
+ call void @foo(ptr %ptr)
+ %b = load i8, ptr %ptr, !invariant.group !0
+
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @unoptimizable3() {
define i8 @unoptimizable3() {
+; CHECK-LABEL: define i8 @unoptimizable3() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: [[PTR2:%.*]] = call ptr @getPointer(ptr [[PTR]])
+; CHECK-NEXT: [[A:%.*]] = load i8, ptr [[PTR2]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: ret i8 [[A]]
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- %ptr2 = call ptr @getPointer(ptr %ptr)
- %a = load i8, ptr %ptr2, !invariant.group !0
-
-; CHECK: ret i8 %a
- ret i8 %a
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ %ptr2 = call ptr @getPointer(ptr %ptr)
+ %a = load i8, ptr %ptr2, !invariant.group !0
+
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @optimizable4() {
define i8 @optimizable4() {
+; CHECK-LABEL: define i8 @optimizable4() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: [[PTR2:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[PTR]])
+; CHECK-NEXT: ret i8 42
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
-; CHECK-NOT: load
- %a = load i8, ptr %ptr2, !invariant.group !0
-
-; CHECK: ret i8 42
- ret i8 %a
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ %ptr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
+ %a = load i8, ptr %ptr2, !invariant.group !0
+
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @volatile1() {
define i8 @volatile1() {
+; CHECK-LABEL: define i8 @volatile1() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[B:%.*]] = load volatile i8, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @bar(i8 [[B]])
+; CHECK-NEXT: [[C:%.*]] = load volatile i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[C]])
+; CHECK-NEXT: ret i8 42
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- call void @foo(ptr %ptr)
- %a = load i8, ptr %ptr, !invariant.group !0
- %b = load volatile i8, ptr %ptr
-; CHECK: call void @bar(i8 %b)
- call void @bar(i8 %b)
-
- %c = load volatile i8, ptr %ptr, !invariant.group !0
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ call void @foo(ptr %ptr)
+ %a = load i8, ptr %ptr, !invariant.group !0
+ %b = load volatile i8, ptr %ptr
+ call void @bar(i8 %b)
+
+ %c = load volatile i8, ptr %ptr, !invariant.group !0
; FIXME: we could change %c to 42, preserving volatile load
-; CHECK: call void @bar(i8 %c)
- call void @bar(i8 %c)
-; CHECK: ret i8 42
- ret i8 %a
+ call void @bar(i8 %c)
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @volatile2() {
define i8 @volatile2() {
+; CHECK-LABEL: define i8 @volatile2() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: [[B:%.*]] = load volatile i8, ptr [[PTR]], align 1
+; CHECK-NEXT: call void @bar(i8 [[B]])
+; CHECK-NEXT: [[C:%.*]] = load volatile i8, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[C]])
+; CHECK-NEXT: ret i8 42
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- call void @foo(ptr %ptr)
- %a = load i8, ptr %ptr, !invariant.group !0
- %b = load volatile i8, ptr %ptr
-; CHECK: call void @bar(i8 %b)
- call void @bar(i8 %b)
-
- %c = load volatile i8, ptr %ptr, !invariant.group !0
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ call void @foo(ptr %ptr)
+ %a = load i8, ptr %ptr, !invariant.group !0
+ %b = load volatile i8, ptr %ptr
+ call void @bar(i8 %b)
+
+ %c = load volatile i8, ptr %ptr, !invariant.group !0
; FIXME: we could change %c to 42, preserving volatile load
-; CHECK: call void @bar(i8 %c)
- call void @bar(i8 %c)
-; CHECK: ret i8 42
- ret i8 %a
+ call void @bar(i8 %c)
+ ret i8 %a
}
-; CHECK-LABEL: define i8 @fun() {
define i8 @fun() {
+; CHECK-LABEL: define i8 @fun() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[PTR:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 42, ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @foo(ptr [[PTR]])
+; CHECK-NEXT: call void @bar(i8 42)
+; CHECK-NEXT: [[NEWPTR:%.*]] = call ptr @getPointer(ptr [[PTR]])
+; CHECK-NEXT: [[C:%.*]] = load i8, ptr [[NEWPTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[C]])
+; CHECK-NEXT: [[UNKNOWNVALUE:%.*]] = load i8, ptr @unknownPtr, align 1
+; CHECK-NEXT: store i8 [[UNKNOWNVALUE]], ptr [[PTR]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: [[NEWPTR2:%.*]] = call ptr @llvm.launder.invariant.group.p0(ptr [[PTR]])
+; CHECK-NEXT: ret i8 [[UNKNOWNVALUE]]
+;
entry:
- %ptr = alloca i8
- store i8 42, ptr %ptr, !invariant.group !0
- call void @foo(ptr %ptr)
-
- %a = load i8, ptr %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
-; CHECK: call void @bar(i8 42)
- call void @bar(i8 %a)
-
- %newPtr = call ptr @getPointer(ptr %ptr)
- %c = load i8, ptr %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
-; CHECK: call void @bar(i8 %c)
- call void @bar(i8 %c)
-
- %unknownValue = load i8, ptr @unknownPtr
+ %ptr = alloca i8
+ store i8 42, ptr %ptr, !invariant.group !0
+ call void @foo(ptr %ptr)
+
+ %a = load i8, ptr %ptr, !invariant.group !0 ; Can assume that value under %ptr didn't change
+ call void @bar(i8 %a)
+
+ %newPtr = call ptr @getPointer(ptr %ptr)
+ %c = load i8, ptr %newPtr, !invariant.group !0 ; Can't assume anything, because we only have information about %ptr
+ call void @bar(i8 %c)
+
+ %unknownValue = load i8, ptr @unknownPtr
; FIXME: Can assume that %unknownValue == 42
-; CHECK: store i8 %unknownValue, ptr %ptr, align 1, !invariant.group !0
- store i8 %unknownValue, ptr %ptr, !invariant.group !0
-
- %newPtr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
-; CHECK-NOT: load
- %d = load i8, ptr %newPtr2, !invariant.group !0
-; CHECK: ret i8 %unknownValue
- ret i8 %d
+ store i8 %unknownValue, ptr %ptr, !invariant.group !0
+
+ %newPtr2 = call ptr @llvm.launder.invariant.group.p0(ptr %ptr)
+ %d = load i8, ptr %newPtr2, !invariant.group !0
+ ret i8 %d
}
; This test checks if invariant.group understands gep with zeros
-; CHECK-LABEL: define void @testGEP0() {
define void @testGEP0() {
+; CHECK-LABEL: define void @testGEP0() {
+; CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 8
+; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2), ptr [[A]], align 8, !invariant.group [[META0]]
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr nonnull dereferenceable(8) [[A]])
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @unknownPtr, align 4
+; CHECK-NEXT: [[TMP2:%.*]] = icmp eq i8 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[TMP2]], label %[[_Z1GR1A_EXIT:.*]], label %[[BB3:.*]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr nonnull [[A]])
+; CHECK-NEXT: br label %[[_Z1GR1A_EXIT]]
+; CHECK: [[_Z1GR1A_EXIT]]:
+; CHECK-NEXT: ret void
+;
%a = alloca %struct.A, align 8
store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2), ptr %a, align 8, !invariant.group !0
-; CHECK: call void @_ZN1A3fooEv(ptr nonnull dereferenceable(8) %a)
call void @_ZN1A3fooEv(ptr nonnull dereferenceable(8) %a) ; This call may change vptr
%1 = load i8, ptr @unknownPtr, align 4
%2 = icmp eq i8 %1, 0
@@ -326,7 +441,6 @@ define void @testGEP0() {
; This should be devirtualized by invariant.group
%4 = load ptr, ptr %a, align 8, !invariant.group !0
%5 = load ptr, ptr %4, align 8
-; CHECK: call void @_ZN1A3fooEv(ptr nonnull %a)
call void %5(ptr nonnull %a)
br label %_Z1gR1A.exit
@@ -337,51 +451,86 @@ _Z1gR1A.exit: ; preds = %0, %3
; Check if no optimizations are performed with global pointers.
; FIXME: we could do the optimizations if we would check if dependency comes
; from the same function.
-; CHECK-LABEL: define void @testGlobal() {
define void @testGlobal() {
-; CHECK: %a = load i8, ptr @unknownPtr, align 1, !invariant.group !0
- %a = load i8, ptr @unknownPtr, !invariant.group !0
- call void @foo2(ptr @unknownPtr, i8 %a)
-; CHECK: %1 = load i8, ptr @unknownPtr, align 1, !invariant.group !0
- %1 = load i8, ptr @unknownPtr, !invariant.group !0
- call void @bar(i8 %1)
-
- call void @fooBit(ptr @unknownPtr, i1 1)
+; CHECK-LABEL: define void @testGlobal() {
+; CHECK-NEXT: [[A:%.*]] = load i8, ptr @unknownPtr, align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @foo2(ptr @unknownPtr, i8 [[A]])
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @unknownPtr, align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @bar(i8 [[TMP1]])
+; CHECK-NEXT: call void @fooBit(ptr @unknownPtr, i1 true)
+; CHECK-NEXT: [[TMP2:%.*]] = load i1, ptr @unknownPtr, align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @fooBit(ptr @unknownPtr, i1 [[TMP2]])
+; CHECK-NEXT: [[TMP3:%.*]] = load i1, ptr @unknownPtr, align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @fooBit(ptr @unknownPtr, i1 [[TMP3]])
+; CHECK-NEXT: ret void
+;
+ %a = load i8, ptr @unknownPtr, !invariant.group !0
+ call void @foo2(ptr @unknownPtr, i8 %a)
+ %1 = load i8, ptr @unknownPtr, !invariant.group !0
+ call void @bar(i8 %1)
+
+ call void @fooBit(ptr @unknownPtr, i1 1)
; Adding regex because of canonicalization of bitcasts
-; CHECK: %2 = load i1, ptr {{.*}}, !invariant.group !0
- %2 = load i1, ptr @unknownPtr, !invariant.group !0
- call void @fooBit(ptr @unknownPtr, i1 %2)
-; CHECK: %3 = load i1, ptr {{.*}}, !invariant.group !0
- %3 = load i1, ptr @unknownPtr, !invariant.group !0
- call void @fooBit(ptr @unknownPtr, i1 %3)
- ret void
+ %2 = load i1, ptr @unknownPtr, !invariant.group !0
+ call void @fooBit(ptr @unknownPtr, i1 %2)
+ %3 = load i1, ptr @unknownPtr, !invariant.group !0
+ call void @fooBit(ptr @unknownPtr, i1 %3)
+ ret void
}
; And in the case it is not global
-; CHECK-LABEL: define void @testNotGlobal() {
define void @testNotGlobal() {
- %a = alloca i8
- call void @foo(ptr %a)
-; CHECK: %b = load i8, ptr %a, align 1, !invariant.group !0
- %b = load i8, ptr %a, !invariant.group !0
- call void @foo2(ptr %a, i8 %b)
-
- %1 = load i8, ptr %a, !invariant.group !0
-; CHECK: call void @bar(i8 %b)
- call void @bar(i8 %1)
-
- call void @fooBit(ptr %a, i1 1)
-; CHECK: %1 = trunc i8 %b to i1
- %2 = load i1, ptr %a, !invariant.group !0
-; CHECK-NEXT: call void @fooBit(ptr %a, i1 %1)
- call void @fooBit(ptr %a, i1 %2)
- %3 = load i1, ptr %a, !invariant.group !0
-; CHECK-NEXT: call void @fooBit(ptr %a, i1 %1)
- call void @fooBit(ptr %a, i1 %3)
- ret void
+; CHECK-LABEL: define void @testNotGlobal() {
+; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
+; CHECK-NEXT: call void @foo(ptr [[A]])
+; CHECK-NEXT: [[B:%.*]] = load i8, ptr [[A]], align 1, !invariant.group [[META0]]
+; CHECK-NEXT: call void @foo2(ptr [[A]], i8 [[B]])
+; CHECK-NEXT: call void @bar(i8 [[B]])
+; CHECK-NEXT: call void @fooBit(ptr [[A]], i1 true)
+; CHECK-NEXT: [[TMP1:%.*]] = trunc i8 [[B]] to i1
+; CHECK-NEXT: call void @fooBit(ptr [[A]], i1 [[TMP1]])
+; CHECK-NEXT: call void @fooBit(ptr [[A]], i1 [[TMP1]])
+; CHECK-NEXT: ret void
+;
+ %a = alloca i8
+ call void @foo(ptr %a)
+ %b = load i8, ptr %a, !invariant.group !0
+ call void @foo2(ptr %a, i8 %b)
+
+ %1 = load i8, ptr %a, !invariant.group !0
+ call void @bar(i8 %1)
+
+ call void @fooBit(ptr %a, i1 1)
+ %2 = load i1, ptr %a, !invariant.group !0
+ call void @fooBit(ptr %a, i1 %2)
+ %3 = load i1, ptr %a, !invariant.group !0
+ call void @fooBit(ptr %a, i1 %3)
+ ret void
}
-; CHECK-LABEL: define void @handling_loops()
define void @handling_loops() {
+; CHECK-LABEL: define void @handling_loops() {
+; CHECK-NEXT: [[A:%.*]] = alloca [[STRUCT_A:%.*]], align 8
+; CHECK-NEXT: store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2), ptr [[A]], align 8, !invariant.group [[META0]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i8, ptr @unknownPtr, align 4
+; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i8 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[TMP2]], [[DOTLR_PH_I:label %.*]], label %[[_Z2G2R1A_EXIT:.*]]
+; CHECK: [[_LR_PH_I:.*:]]
+; CHECK-NEXT: [[TMP3:%.*]] = icmp sgt i8 [[TMP1]], 1
+; CHECK-NEXT: br i1 [[TMP3]], label %[[DOT_CRIT_EDGE_PREHEADER:.*]], label %[[_Z2G2R1A_EXIT]]
+; CHECK: [[__CRIT_EDGE_PREHEADER:.*:]]
+; CHECK-NEXT: br label %[[DOT_CRIT_EDGE:.*]]
+; CHECK: [[__CRIT_EDGE:.*:]]
+; CHECK-NEXT: [[TMP4:%.*]] = phi i8 [ [[TMP5:%.*]], %[[DOT_CRIT_EDGE]] ], [ 1, %[[DOT_CRIT_EDGE_PREHEADER]] ]
+; CHECK-NEXT: call void @_ZN1A3fooEv(ptr nonnull [[A]])
+; CHECK-NEXT: [[TMP5]] = add nuw nsw i8 [[TMP4]], 1
+; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr @unknownPtr, align 4
+; CHECK-NEXT: [[TMP7:%.*]] = icmp slt i8 [[TMP5]], [[TMP6]]
+; CHECK-NEXT: br i1 [[TMP7]], label %[[DOT_CRIT_EDGE]], label %[[_Z2G2R1A_EXIT_LOOPEXIT:.*]]
+; CHECK: [[_Z2G2R1A_EXIT_LOOPEXIT]]:
+; CHECK-NEXT: br label %[[_Z2G2R1A_EXIT]]
+; CHECK: [[_Z2G2R1A_EXIT]]:
+; CHECK-NEXT: ret void
+;
%a = alloca %struct.A, align 8
store ptr getelementptr inbounds ([3 x ptr], ptr @_ZTV1A, i64 0, i64 2), ptr %a, align 8, !invariant.group !0
%1 = load i8, ptr @unknownPtr, align 4
@@ -400,9 +549,7 @@ define void @handling_loops() {
%5 = phi i8 [ %7, %._crit_edge ], [ 1, %._crit_edge.preheader ]
%.pre = load ptr, ptr %a, align 8, !invariant.group !0
%6 = load ptr, ptr %.pre, align 8
- ; CHECK: call void @_ZN1A3fooEv(ptr nonnull %a)
call void %6(ptr nonnull %a) #3
- ; CHECK-NOT: call void %
%7 = add nuw nsw i8 %5, 1
%8 = load i8, ptr @unknownPtr, align 4
%9 = icmp slt i8 %7, %8
@@ -432,3 +579,6 @@ declare void @llvm.assume(i1 %cmp.vtables)
!0 = !{}
+;.
+; CHECK: [[META0]] = !{}
+;.
diff --git a/llvm/test/Transforms/GVN/invariant.start.ll b/llvm/test/Transforms/GVN/invariant.start.ll
index f2d7dd05a01d41..1c03a8d8742edf 100644
--- a/llvm/test/Transforms/GVN/invariant.start.ll
+++ b/llvm/test/Transforms/GVN/invariant.start.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; Test to make sure llvm.invariant.start calls are not treated as clobbers.
; RUN: opt < %s -passes=gvn -S | FileCheck %s
@@ -7,10 +8,12 @@ declare void @llvm.invariant.end.p0(ptr, i64, ptr nocapture) nounwind
; We forward store to the load across the invariant.start intrinsic
define i8 @forward_store() {
-; CHECK-LABEL: @forward_store
-; CHECK: call ptr @llvm.invariant.start.p0(i64 1, ptr %a)
-; CHECK-NOT: load
-; CHECK: ret i8 0
+; CHECK-LABEL: define i8 @forward_store() {
+; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 0, ptr [[A]], align 1
+; CHECK-NEXT: [[I:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]])
+; CHECK-NEXT: ret i8 0
+;
%a = alloca i8
store i8 0, ptr %a
%i = call ptr @llvm.invariant.start.p0(i64 1, ptr %a)
@@ -23,10 +26,18 @@ declare i8 @dummy(ptr nocapture) nounwind readonly
; We forward store to the load in the non-local analysis case,
; i.e. invariant.start is in another basic block.
define i8 @forward_store_nonlocal(i1 %cond) {
-; CHECK-LABEL: forward_store_nonlocal
-; CHECK: call ptr @llvm.invariant.start.p0(i64 1, ptr %a)
-; CHECK: ret i8 0
-; CHECK: ret i8 %val
+; CHECK-LABEL: define i8 @forward_store_nonlocal(
+; CHECK-SAME: i1 [[COND:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 0, ptr [[A]], align 1
+; CHECK-NEXT: [[I:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]])
+; CHECK-NEXT: br i1 [[COND]], label %[[LOADBLOCK:.*]], label %[[EXIT:.*]]
+; CHECK: [[LOADBLOCK]]:
+; CHECK-NEXT: ret i8 0
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[VAL:%.*]] = call i8 @dummy(ptr [[A]])
+; CHECK-NEXT: ret i8 [[VAL]]
+;
%a = alloca i8
store i8 0, ptr %a
%i = call ptr @llvm.invariant.start.p0(i64 1, ptr %a)
@@ -43,12 +54,14 @@ exit:
; We should not value forward %foo to the invariant.end corresponding to %bar.
define i8 @forward_store1() {
-; CHECK-LABEL: forward_store1
-; CHECK: %foo = call ptr @llvm.invariant.start.p0
-; CHECK-NOT: load
-; CHECK: %bar = call ptr @llvm.invariant.start.p0
-; CHECK: call void @llvm.invariant.end.p0(ptr %bar, i64 1, ptr %a)
-; CHECK: ret i8 0
+; CHECK-LABEL: define i8 @forward_store1() {
+; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 0, ptr [[A]], align 1
+; CHECK-NEXT: [[FOO:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]])
+; CHECK-NEXT: [[BAR:%.*]] = call ptr @llvm.invariant.start.p0(i64 1, ptr [[A]])
+; CHECK-NEXT: call void @llvm.invariant.end.p0(ptr [[BAR]], i64 1, ptr [[A]])
+; CHECK-NEXT: ret i8 0
+;
%a = alloca i8
store i8 0, ptr %a
%foo = call ptr @llvm.invariant.start.p0(i64 1, ptr %a)
diff --git a/llvm/test/Transforms/GVN/lifetime-simple.ll b/llvm/test/Transforms/GVN/lifetime-simple.ll
index bf7a6ef754b02b..1d3c7c19488806 100644
--- a/llvm/test/Transforms/GVN/lifetime-simple.ll
+++ b/llvm/test/Transforms/GVN/lifetime-simple.ll
@@ -1,12 +1,19 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=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(ptr %P) nounwind {
-; CHECK: lifetime.start
-; CHECK-NOT: load
-; CHECK: lifetime.end
+; CHECK-LABEL: define i8 @test(
+; CHECK-SAME: ptr [[P:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: call void @llvm.lifetime.start.p0(i64 32, ptr [[P]])
+; CHECK-NEXT: store i8 1, ptr [[P]], align 1
+; CHECK-NEXT: call void @llvm.lifetime.end.p0(i64 32, ptr [[P]])
+; CHECK-NEXT: [[TMP0:%.*]] = load i8, ptr [[P]], align 1
+; CHECK-NEXT: ret i8 [[TMP0]]
+;
entry:
call void @llvm.lifetime.start.p0(i64 32, ptr %P)
%0 = load i8, ptr %P
diff --git a/llvm/test/Transforms/GVN/load-constant-mem.ll b/llvm/test/Transforms/GVN/load-constant-mem.ll
index d5858d6c6113b1..57a157d5a8bf6c 100644
--- a/llvm/test/Transforms/GVN/load-constant-mem.ll
+++ b/llvm/test/Transforms/GVN/load-constant-mem.ll
@@ -1,19 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn,instcombine -S | FileCheck %s
; PR4189
@G = external constant [4 x i32]
define i32 @test(ptr %p, i32 %i) nounwind {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: ptr [[P:%.*]], i32 [[I:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: store i8 4, ptr [[P]], align 1
+; CHECK-NEXT: ret i32 0
+;
entry:
- %P = getelementptr [4 x i32], ptr @G, i32 0, i32 %i
- %A = load i32, ptr %P
- store i8 4, ptr %p
- %B = load i32, ptr %P
- %C = sub i32 %A, %B
- ret i32 %C
+ %P = getelementptr [4 x i32], ptr @G, i32 0, i32 %i
+ %A = load i32, ptr %P
+ store i8 4, ptr %p
+ %B = load i32, ptr %P
+ %C = sub i32 %A, %B
+ ret i32 %C
}
-; CHECK: define i32 @test(ptr %p, i32 %i) #0 {
-; CHECK-NEXT: entry:
-; CHECK-NEXT: store i8 4, ptr %p, align 1
-; CHECK-NEXT: ret i32 0
-; CHECK-NEXT: }
diff --git a/llvm/test/Transforms/GVN/load-from-unreachable-predecessor.ll b/llvm/test/Transforms/GVN/load-from-unreachable-predecessor.ll
index 6ad0f59dbe292e..9daa39d79fa640 100644
--- a/llvm/test/Transforms/GVN/load-from-unreachable-predecessor.ll
+++ b/llvm/test/Transforms/GVN/load-from-unreachable-predecessor.ll
@@ -1,12 +1,23 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
; Check that an unreachable predecessor to a PHI node doesn't cause a crash.
; PR21625.
define i32 @f(ptr %f) {
-; CHECK: bb0:
+; CHECK-LABEL: define i32 @f(
+; CHECK-SAME: ptr [[F:%.*]]) {
+; CHECK-NEXT: [[BB0:.*]]:
+; CHECK-NEXT: br label %[[BB2:.*]]
+; CHECK: [[BB1:.*]]:
+; CHECK-NEXT: [[ZED:%.*]] = load ptr, ptr [[F]], align 8
+; CHECK-NEXT: br i1 false, label %[[BB1]], label %[[BB2]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: [[FOO:%.*]] = phi ptr [ null, %[[BB0]] ], [ [[ZED]], %[[BB1]] ]
+; CHECK-NEXT: [[STOREMERGE:%.*]] = load i32, ptr [[FOO]], align 4
+; CHECK-NEXT: ret i32 [[STOREMERGE]]
+;
; Load should be removed, since it's ignored.
-; CHECK-NEXT: br label
bb0:
%bar = load ptr, ptr %f
br label %bb2
diff --git a/llvm/test/Transforms/GVN/malloc-load-removal.ll b/llvm/test/Transforms/GVN/malloc-load-removal.ll
index 96b5bef5031e79..d38a652a58260c 100644
--- a/llvm/test/Transforms/GVN/malloc-load-removal.ll
+++ b/llvm/test/Transforms/GVN/malloc-load-removal.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=gvn < %s | FileCheck %s
; PR13694
@@ -7,6 +8,17 @@ target triple = "x86_64-apple-macosx10.8.0"
declare noalias ptr @malloc(i64) nounwind allockind("alloc,uninitialized") allocsize(0)
define noalias ptr @test1() nounwind uwtable ssp {
+; CHECK-LABEL: define noalias ptr @test1(
+; CHECK-SAME: ) #[[ATTR1:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @malloc(i64 100) #[[ATTR2:[0-9]+]]
+; CHECK-NEXT: br i1 undef, label %[[IF_END:.*]], label %[[IF_THEN:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: store i8 0, ptr [[CALL]], align 1
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: ret ptr [[CALL]]
+;
entry:
%call = tail call ptr @malloc(i64 100) nounwind
%0 = load i8, ptr %call, align 1
@@ -20,9 +32,6 @@ if.then: ; preds = %entry
if.end: ; preds = %if.then, %entry
ret ptr %call
-; CHECK-LABEL: @test1(
-; CHECK-NOT: load
-; CHECK-NOT: icmp
; CHECK_NO_LIBCALLS-LABEL: @test1(
; CHECK_NO_LIBCALLS: load
@@ -32,6 +41,17 @@ if.end: ; preds = %if.then, %entry
declare noalias ptr @_Znwm(i64) nounwind
define noalias ptr @test2() nounwind uwtable ssp {
+; CHECK-LABEL: define noalias ptr @test2(
+; CHECK-SAME: ) #[[ATTR1]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @_Znwm(i64 100) #[[ATTR2]]
+; CHECK-NEXT: br i1 undef, label %[[IF_END:.*]], label %[[IF_THEN:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: store i8 0, ptr [[CALL]], align 1
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: ret ptr [[CALL]]
+;
entry:
%call = tail call ptr @_Znwm(i64 100) nounwind
%0 = load i8, ptr %call, align 1
@@ -45,9 +65,6 @@ if.then: ; preds = %entry
if.end: ; preds = %if.then, %entry
ret ptr %call
-; CHECK-LABEL: @test2(
-; CHECK-NOT: load
-; CHECK-NOT: icmp
; CHECK_NO_LIBCALLS-LABEL: @test2(
; CHECK_NO_LIBCALLS: load
@@ -57,6 +74,17 @@ if.end: ; preds = %if.then, %entry
declare noalias ptr @aligned_alloc(i64 allocalign, i64) nounwind allockind("alloc,uninitialized,aligned") allocsize(1)
define noalias ptr @test3() nounwind uwtable ssp {
+; CHECK-LABEL: define noalias ptr @test3(
+; CHECK-SAME: ) #[[ATTR1]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[CALL:%.*]] = tail call ptr @aligned_alloc(i64 256, i64 32) #[[ATTR2]]
+; CHECK-NEXT: br i1 undef, label %[[IF_END:.*]], label %[[IF_THEN:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: store i8 0, ptr [[CALL]], align 1
+; CHECK-NEXT: br label %[[IF_END]]
+; CHECK: [[IF_END]]:
+; CHECK-NEXT: ret ptr [[CALL]]
+;
entry:
%call = tail call ptr @aligned_alloc(i64 256, i64 32) nounwind
%0 = load i8, ptr %call, align 32
@@ -70,9 +98,6 @@ if.then: ; preds = %entry
if.end: ; preds = %if.then, %entry
ret ptr %call
-; CHECK-LABEL: @test3(
-; CHECK-NOT: load
-; CHECK-NOT: icmp
; CHECK_NO_LIBCALLS-LABEL: @test3(
; CHECK_NO_LIBCALLS: load
diff --git a/llvm/test/Transforms/GVN/no-mem-dep-info.ll b/llvm/test/Transforms/GVN/no-mem-dep-info.ll
index 0380b7ef10733b..fc953463b4bdd1 100644
--- a/llvm/test/Transforms/GVN/no-mem-dep-info.ll
+++ b/llvm/test/Transforms/GVN/no-mem-dep-info.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt %s -passes=gvn -S -enable-gvn-memdep=false | FileCheck %s
; RUN: opt %s -passes=gvn -S -enable-gvn-memdep=true | FileCheck %s
@@ -11,6 +12,17 @@ declare <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float>, ptr, <8 x i32>,
; Function Attrs: nounwind
define <8 x float> @foo1(ptr noalias readonly %arr.ptr, ptr noalias readonly %vix.ptr, ptr noalias %t2.ptr) #1 {
+; CHECK-LABEL: define <8 x float> @foo1(
+; CHECK-SAME: ptr noalias readonly [[ARR_PTR:%.*]], ptr noalias readonly [[VIX_PTR:%.*]], ptr noalias [[T2_PTR:%.*]]) {
+; CHECK-NEXT: [[ALLOCAS:.*:]]
+; CHECK-NEXT: [[VIX:%.*]] = load <8 x i32>, ptr [[VIX_PTR]], align 4
+; CHECK-NEXT: [[T1_PTR:%.*]] = getelementptr i8, ptr [[ARR_PTR]], i8 4
+; CHECK-NEXT: [[V1:%.*]] = tail call <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float> undef, ptr [[ARR_PTR]], <8 x i32> [[VIX]], <8 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, i8 1)
+; CHECK-NEXT: store i8 1, ptr [[T1_PTR]], align 4
+; CHECK-NEXT: [[V2:%.*]] = tail call <8 x float> @llvm.x86.avx2.gather.d.ps.256(<8 x float> undef, ptr [[ARR_PTR]], <8 x i32> [[VIX]], <8 x float> <float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000, float 0xFFFFFFFFE0000000>, i8 1)
+; CHECK-NEXT: [[RES:%.*]] = fadd <8 x float> [[V1]], [[V2]]
+; CHECK-NEXT: ret <8 x float> [[RES]]
+;
allocas:
%vix = load <8 x i32>, ptr %vix.ptr, align 4
%t1.ptr = getelementptr i8, ptr %arr.ptr, i8 4
@@ -23,7 +35,3 @@ allocas:
ret <8 x float> %res
}
-; CHECK: foo1
-; CHECK: llvm.x86.avx2.gather.d.ps.256
-; CHECK: store
-; CHECK: llvm.x86.avx2.gather.d.ps.256
diff --git a/llvm/test/Transforms/GVN/noalias.ll b/llvm/test/Transforms/GVN/noalias.ll
index 931564db47b398..66debd996d99ca 100644
--- a/llvm/test/Transforms/GVN/noalias.ll
+++ b/llvm/test/Transforms/GVN/noalias.ll
@@ -1,10 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
define i32 @test1(ptr %p, ptr %q) {
-; CHECK-LABEL: @test1(ptr %p, ptr %q)
-; CHECK: load i32, ptr %p
-; CHECK-NOT: noalias
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test1(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = load i32, ptr %p, !noalias !3
%b = load i32, ptr %p
%c = add i32 %a, %b
@@ -12,9 +15,12 @@ define i32 @test1(ptr %p, ptr %q) {
}
define i32 @test2(ptr %p, ptr %q) {
-; CHECK-LABEL: @test2(ptr %p, ptr %q)
-; CHECK: load i32, ptr %p, align 4, !alias.scope ![[SCOPE1:[0-9]+]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test2(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !alias.scope [[META0:![0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = load i32, ptr %p, !alias.scope !3
%b = load i32, ptr %p, !alias.scope !3
%c = add i32 %a, %b
@@ -22,17 +28,18 @@ define i32 @test2(ptr %p, ptr %q) {
}
define i32 @test3(ptr %p, ptr %q) {
-; CHECK-LABEL: @test3(ptr %p, ptr %q)
-; CHECK: load i32, ptr %p, align 4, !alias.scope ![[SCOPE2:[0-9]+]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test3(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = load i32, ptr [[P]], align 4, !alias.scope [[META3:![0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = load i32, ptr %p, !alias.scope !4
%b = load i32, ptr %p, !alias.scope !5
%c = add i32 %a, %b
ret i32 %c
}
-; CHECK: ![[SCOPE1]] = !{!{{[0-9]+}}}
-; CHECK: ![[SCOPE2]] = !{!{{[0-9]+}}, !{{[0-9]+}}}
declare i32 @foo(ptr) readonly
!0 = distinct !{!0, !2, !"callee0: %a"}
@@ -42,3 +49,10 @@ declare i32 @foo(ptr) readonly
!3 = !{!0}
!4 = !{!1}
!5 = !{!0, !1}
+;.
+; CHECK: [[META0]] = !{[[META1:![0-9]+]]}
+; CHECK: [[META1]] = distinct !{[[META1]], [[META2:![0-9]+]], !"callee0: %a"}
+; CHECK: [[META2]] = distinct !{[[META2]], !"callee0"}
+; CHECK: [[META3]] = !{[[META4:![0-9]+]], [[META1]]}
+; CHECK: [[META4]] = distinct !{[[META4]], [[META2]], !"callee0: %b"}
+;.
diff --git a/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll b/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll
index c0afce55cb3e87..ab5c53f2ecca89 100644
--- a/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll
+++ b/llvm/test/Transforms/GVN/non-integral-pointers-inseltpoison.ll
@@ -369,7 +369,7 @@ entry:
declare void @use.v2(<2 x ptr addrspace(4)>)
declare void @use.v4(<4 x ptr addrspace(4)>)
- define ptr addrspace(5) @multini(i1 %alwaysFalse, ptr addrspace(4) %val, ptr %loc) {
+ define ptr addrspace(5) @multini(i1 %alwaysFalse, ptr addrspace(4) %val, ptr %loc) {
; CHECK-LABEL: @multini(
; CHECK-NEXT: entry:
; CHECK-NEXT: store ptr addrspace(4) [[VAL:%.*]], ptr [[LOC:%.*]], align 8
diff --git a/llvm/test/Transforms/GVN/non-local-offset.ll b/llvm/test/Transforms/GVN/non-local-offset.ll
index 0467657f965551..746ee0606bc504 100644
--- a/llvm/test/Transforms/GVN/non-local-offset.ll
+++ b/llvm/test/Transforms/GVN/non-local-offset.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
target datalayout = "e-p:64:64:64"
@@ -5,12 +6,21 @@ target datalayout = "e-p:64:64:64"
; GVN should ignore the store to p[1] to see that the load from p[0] is
; fully redundant.
-; CHECK-LABEL: @yes(
-; CHECK: if.then:
-; CHECK-NEXT: store i32 0, ptr %q
-; CHECK-NEXT: ret void
define void @yes(i1 %c, ptr %p, ptr %q) nounwind {
+; CHECK-LABEL: define void @yes(
+; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: store i32 0, ptr [[P]], align 4
+; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
+; CHECK-NEXT: store i32 1, ptr [[P1]], align 4
+; CHECK-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: store i32 0, ptr [[Q]], align 4
+; CHECK-NEXT: ret void
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: ret void
+;
entry:
store i32 0, ptr %p
%p1 = getelementptr inbounds i32, ptr %p, i64 1
@@ -30,15 +40,23 @@ if.else:
; fully redundant. However, the second load is larger, so it's not a simple
; redundancy.
-; CHECK-LABEL: @watch_out_for_size_change(
-; CHECK: if.then:
-; CHECK-NEXT: store i32 0, ptr %q
-; CHECK-NEXT: ret void
-; CHECK: if.else:
-; CHECK: load i64, ptr %p
-; CHECK: store i64
define void @watch_out_for_size_change(i1 %c, ptr %p, ptr %q) nounwind {
+; CHECK-LABEL: define void @watch_out_for_size_change(
+; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]], ptr [[Q:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: store i32 0, ptr [[P]], align 4
+; CHECK-NEXT: [[P1:%.*]] = getelementptr inbounds i32, ptr [[P]], i64 1
+; CHECK-NEXT: store i32 1, ptr [[P1]], align 4
+; CHECK-NEXT: br i1 [[C]], label %[[IF_ELSE:.*]], label %[[IF_THEN:.*]]
+; CHECK: [[IF_THEN]]:
+; CHECK-NEXT: store i32 0, ptr [[Q]], align 4
+; CHECK-NEXT: ret void
+; CHECK: [[IF_ELSE]]:
+; CHECK-NEXT: [[T64:%.*]] = load i64, ptr [[P]], align 4
+; CHECK-NEXT: store i64 [[T64]], ptr [[Q]], align 4
+; CHECK-NEXT: ret void
+;
entry:
store i32 0, ptr %p
%p1 = getelementptr inbounds i32, ptr %p, i64 1
diff --git a/llvm/test/Transforms/GVN/phi-translate-partial-alias.ll b/llvm/test/Transforms/GVN/phi-translate-partial-alias.ll
index a1029762ad4a4b..8bd388cc40e7ab 100644
--- a/llvm/test/Transforms/GVN/phi-translate-partial-alias.ll
+++ b/llvm/test/Transforms/GVN/phi-translate-partial-alias.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %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-f128:128:128-n8:16:32:64"
@@ -6,12 +7,19 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
; not actually redundant around the loop backedge, despite appearances
; if phi-translation is ignored.
-; CHECK: define void @test0(ptr %begin)
-; CHECK: loop:
-; CHECK: %l0 = load i8, ptr %phi
-; CHECK: call void @bar(i8 %l0)
-; CHECK: %l1 = load i8, ptr %phi
define void @test0(ptr %begin) {
+; CHECK-LABEL: define void @test0(
+; CHECK-SAME: ptr [[BEGIN:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[PHI:%.*]] = phi ptr [ [[BEGIN]], %[[ENTRY]] ], [ [[NEXT:%.*]], %[[LOOP]] ]
+; CHECK-NEXT: [[L0:%.*]] = load i8, ptr [[PHI]], align 1
+; CHECK-NEXT: call void @bar(i8 [[L0]])
+; CHECK-NEXT: [[L1:%.*]] = load i8, ptr [[PHI]], align 1
+; CHECK-NEXT: [[NEXT]] = getelementptr inbounds i8, ptr [[PHI]], i8 [[L1]]
+; CHECK-NEXT: br label %[[LOOP]]
+;
entry:
br label %loop
diff --git a/llvm/test/Transforms/GVN/pr10820.ll b/llvm/test/Transforms/GVN/pr10820.ll
index 48b13a405f0e30..46aeef32112830 100644
--- a/llvm/test/Transforms/GVN/pr10820.ll
+++ b/llvm/test/Transforms/GVN/pr10820.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
target datalayout =
@@ -7,12 +8,16 @@ target triple = "x86_64-unknown-linux-gnu"
@g = external global i31
define void @main() nounwind uwtable {
+; CHECK-LABEL: define void @main(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: store i32 402662078, ptr @g, align 8
+; CHECK-NEXT: store i31 402662078, ptr undef, align 1
+; CHECK-NEXT: unreachable
+;
entry:
-; CHECK: store i32
store i32 402662078, ptr @g, align 8
-; CHECK-NOT: load i31
%0 = load i31, ptr @g, align 8
-; CHECK: store i31
store i31 %0, ptr undef, align 1
unreachable
}
diff --git a/llvm/test/Transforms/GVN/pr12979.ll b/llvm/test/Transforms/GVN/pr12979.ll
index 2f7a4637a7a5a3..8e706a5a066586 100644
--- a/llvm/test/Transforms/GVN/pr12979.ll
+++ b/llvm/test/Transforms/GVN/pr12979.ll
@@ -1,9 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
define i32 @test1(i32 %x, i32 %y) {
-; CHECK: @test1(i32 %x, i32 %y)
-; CHECK: %add1 = add i32 %x, %y
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test1(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add nsw i32 %x, %y
%add2 = add i32 %x, %y
@@ -12,9 +16,12 @@ define i32 @test1(i32 %x, i32 %y) {
}
define i32 @test2(i32 %x, i32 %y) {
-; CHECK: @test2(i32 %x, i32 %y)
-; CHECK: %add1 = add i32 %x, %y
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test2(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add nuw i32 %x, %y
%add2 = add i32 %x, %y
@@ -23,9 +30,12 @@ define i32 @test2(i32 %x, i32 %y) {
}
define i32 @test3(i32 %x, i32 %y) {
-; CHECK: @test3(i32 %x, i32 %y)
-; CHECK: %add1 = add i32 %x, %y
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test3(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add nuw nsw i32 %x, %y
%add2 = add i32 %x, %y
@@ -34,9 +44,12 @@ define i32 @test3(i32 %x, i32 %y) {
}
define i32 @test4(i32 %x, i32 %y) {
-; CHECK: @test4(i32 %x, i32 %y)
-; CHECK: %add1 = add nsw i32 %x, %y
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test4(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add nsw i32 %x, %y
%add2 = add nsw i32 %x, %y
@@ -45,9 +58,12 @@ define i32 @test4(i32 %x, i32 %y) {
}
define i32 @test5(i32 %x, i32 %y) {
-; CHECK: @test5(i32 %x, i32 %y)
-; CHECK: %add1 = add i32 %x, %y
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test5(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add nuw i32 %x, %y
%add2 = add nsw i32 %x, %y
@@ -56,9 +72,12 @@ define i32 @test5(i32 %x, i32 %y) {
}
define i32 @test6(i32 %x, i32 %y) {
-; CHECK: @test6(i32 %x, i32 %y)
-; CHECK: %add1 = add nsw i32 %x, %y
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test6(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add nsw i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add nuw nsw i32 %x, %y
%add2 = add nsw i32 %x, %y
@@ -67,10 +86,12 @@ define i32 @test6(i32 %x, i32 %y) {
}
define i32 @test7(i32 %x, i32 %y) {
-; CHECK: @test7(i32 %x, i32 %y)
-; CHECK: %add1 = add i32 %x, %y
-; CHECK-NOT: what_is_this
-; CHECK: %foo = add i32 %add1, %add1
+; CHECK-LABEL: define i32 @test7(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ADD1:%.*]] = add i32 [[X]], [[Y]]
+; CHECK-NEXT: [[FOO:%.*]] = add i32 [[ADD1]], [[ADD1]]
+; CHECK-NEXT: ret i32 [[FOO]]
+;
%add1 = add i32 %x, %y, !what_is_this !{}
%add2 = add i32 %x, %y
@@ -81,10 +102,12 @@ define i32 @test7(i32 %x, i32 %y) {
declare void @mumble(i2, i2)
define void @test8(i2 %x) {
-; CHECK-LABEL: @test8(
-; CHECK: %[[ashr:.*]] = ashr i2 %x, 1
-; CHECK-NEXT: call void @mumble(i2 %[[ashr]], i2 %[[ashr]])
-; CHECK-NEXT: ret void
+; CHECK-LABEL: define void @test8(
+; CHECK-SAME: i2 [[X:%.*]]) {
+; CHECK-NEXT: [[ASHR0:%.*]] = ashr i2 [[X]], 1
+; CHECK-NEXT: call void @mumble(i2 [[ASHR0]], i2 [[ASHR0]])
+; CHECK-NEXT: ret void
+;
%ashr0 = ashr exact i2 %x, 1
%ashr1 = ashr i2 %x, 1
diff --git a/llvm/test/Transforms/GVN/pr14166.ll b/llvm/test/Transforms/GVN/pr14166.ll
index 6dc831a6e8c350..fe10d85e4ce8be 100644
--- a/llvm/test/Transforms/GVN/pr14166.ll
+++ b/llvm/test/Transforms/GVN/pr14166.ll
@@ -1,7 +1,17 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -disable-basic-aa -passes=gvn -S < %s | FileCheck %s
target datalayout = "e-p:32:32:32"
target triple = "i386-pc-linux-gnu"
define <2 x i32> @test1() {
+; CHECK-LABEL: define <2 x i32> @test1() {
+; CHECK-NEXT: [[V1:%.*]] = alloca <2 x i32>, align 8
+; CHECK-NEXT: call void @anything(ptr [[V1]])
+; CHECK-NEXT: [[V2:%.*]] = load <2 x i32>, ptr [[V1]], align 8
+; CHECK-NEXT: [[V3:%.*]] = inttoptr <2 x i32> [[V2]] to <2 x ptr>
+; CHECK-NEXT: store <2 x ptr> [[V3]], ptr [[V1]], align 8
+; CHECK-NEXT: [[TMP1:%.*]] = bitcast <2 x i32> [[V2]] to i64
+; CHECK-NEXT: ret <2 x i32> [[V2]]
+;
%v1 = alloca <2 x i32>
call void @anything(ptr %v1)
%v2 = load <2 x i32>, ptr %v1
@@ -9,13 +19,6 @@ define <2 x i32> @test1() {
store <2 x ptr> %v3, ptr %v1
%v5 = load <2 x i32>, ptr %v1
ret <2 x i32> %v5
-; CHECK-LABEL: @test1(
-; CHECK: %v1 = alloca <2 x i32>
-; CHECK: call void @anything(ptr %v1)
-; CHECK: %v2 = load <2 x i32>, ptr %v1
-; CHECK: %v3 = inttoptr <2 x i32> %v2 to <2 x ptr>
-; CHECK: store <2 x ptr> %v3, ptr %v1
-; CHECK: ret <2 x i32> %v2
}
declare void @anything(ptr)
diff --git a/llvm/test/Transforms/GVN/pr17732.ll b/llvm/test/Transforms/GVN/pr17732.ll
index c6ebd7aac18aca..73196f82d625bf 100644
--- a/llvm/test/Transforms/GVN/pr17732.ll
+++ b/llvm/test/Transforms/GVN/pr17732.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S -o - < %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-S128"
@@ -13,6 +14,12 @@ target triple = "x86_64-unknown-linux-gnu"
@vector_with_zeroinit = common global %struct.with_vector zeroinitializer, align 4
define i32 @main() {
+; CHECK-LABEL: define i32 @main() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 @array_with_zeroinit, ptr align 4 @main.obj_with_array, i64 12, i1 false)
+; CHECK-NEXT: tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 @vector_with_zeroinit, ptr align 4 @main.obj_with_vector, i64 12, i1 false)
+; CHECK-NEXT: ret i32 1
+;
entry:
tail call void @llvm.memcpy.p0.p0.i64(ptr align 4 @array_with_zeroinit, ptr align 4 @main.obj_with_array, i64 12, i1 false)
%0 = load i8, ptr getelementptr inbounds (%struct.with_array, ptr @array_with_zeroinit, i64 0, i32 2), align 4
@@ -23,8 +30,6 @@ entry:
%conv1 = sext i8 %1 to i32
%and = and i32 %conv0, %conv1
ret i32 %and
-; CHECK-LABEL: define i32 @main(
-; CHECK: ret i32 1
}
declare void @llvm.memcpy.p0.p0.i64(ptr nocapture, ptr nocapture readonly, i64, i1)
diff --git a/llvm/test/Transforms/GVN/pr24426.ll b/llvm/test/Transforms/GVN/pr24426.ll
index 2a0885750108f3..92ad697f9f9c87 100644
--- a/llvm/test/Transforms/GVN/pr24426.ll
+++ b/llvm/test/Transforms/GVN/pr24426.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=memcpyopt,mldst-motion,gvn -S | FileCheck %s
declare void @check(i8)
@@ -5,11 +6,17 @@ declare void @check(i8)
declare void @write(ptr %res)
define void @test1() {
+; CHECK-LABEL: define void @test1() {
+; CHECK-NEXT: [[TMP1:%.*]] = alloca [10 x i8], align 1
+; CHECK-NEXT: call void @write(ptr [[TMP1]])
+; CHECK-NEXT: [[TMP2:%.*]] = load i8, ptr [[TMP1]], align 1
+; CHECK-NEXT: call void @check(i8 [[TMP2]])
+; CHECK-NEXT: ret void
+;
%1 = alloca [10 x i8]
call void @write(ptr %1)
%2 = load i8, ptr %1
-; CHECK-NOT: undef
call void @check(i8 %2)
ret void
diff --git a/llvm/test/Transforms/GVN/pr25440.ll b/llvm/test/Transforms/GVN/pr25440.ll
index 507111ef1b8ca6..b6ed3951d22be1 100644
--- a/llvm/test/Transforms/GVN/pr25440.ll
+++ b/llvm/test/Transforms/GVN/pr25440.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
;RUN: opt -passes=gvn -S < %s | FileCheck %s
target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n8:16:32-S64"
@@ -10,19 +11,53 @@ target triple = "thumbv7--linux-gnueabi"
; Function Attrs: nounwind
define fastcc void @foo(ptr nocapture readonly %x) {
-;CHECK-LABEL: foo
+; CHECK-LABEL: define fastcc void @foo(
+; CHECK-SAME: ptr nocapture readonly [[X:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br label %[[BB0:.*]]
+; CHECK: [[BB0]]:
+; CHECK-NEXT: [[X_TR:%.*]] = phi ptr [ [[X]], %[[ENTRY]] ], [ null, %[[LAND_LHS_TRUE:.*]] ]
+; CHECK-NEXT: [[TMP0:%.*]] = load i16, ptr [[X_TR]], align 4
+; CHECK-NEXT: [[CONV:%.*]] = zext i16 [[TMP0]] to i32
+; CHECK-NEXT: switch i32 [[CONV]], label %[[IF_END_50:.*]] [
+; CHECK-NEXT: i32 43, label %[[CLEANUP:.*]]
+; CHECK-NEXT: i32 52, label %[[IF_THEN_5:.*]]
+; CHECK-NEXT: ]
+; CHECK: [[IF_THEN_5]]:
+; CHECK-NEXT: br i1 undef, label %[[LAND_LHS_TRUE]], label %[[IF_THEN_26:.*]]
+; CHECK: [[LAND_LHS_TRUE]]:
+; CHECK-NEXT: br i1 undef, label %[[CLEANUP]], label %[[BB0]]
+; CHECK: [[IF_THEN_26]]:
+; CHECK-NEXT: br i1 undef, label %[[COND_END:.*]], label %[[COND_FALSE:.*]]
+; CHECK: [[COND_FALSE]]:
+; CHECK-NEXT: [[MODE:%.*]] = getelementptr inbounds [[STRUCT_A:%.*]], ptr [[X_TR]], i32 0, i32 1
+; CHECK-NEXT: [[BF_LOAD:%.*]] = load i16, ptr [[MODE]], align 2
+; CHECK-NEXT: [[BF_SHL:%.*]] = shl i16 [[BF_LOAD]], 8
+; CHECK-NEXT: br label %[[COND_END]]
+; CHECK: [[COND_END]]:
+; CHECK-NEXT: br i1 undef, label %[[IF_THEN_44:.*]], label %[[CLEANUP]]
+; CHECK: [[IF_THEN_44]]:
+; CHECK-NEXT: unreachable
+; CHECK: [[IF_END_50]]:
+; CHECK-NEXT: [[ARRAYIDX52:%.*]] = getelementptr inbounds [0 x i32], ptr @length, i32 0, i32 [[CONV]]
+; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX52]], align 4
+; CHECK-NEXT: br i1 undef, label %[[FOR_BODY_57:.*]], label %[[CLEANUP]]
+; CHECK: [[FOR_BODY_57]]:
+; CHECK-NEXT: [[I_2157:%.*]] = add nsw i32 [[TMP1]], -1
+; CHECK-NEXT: unreachable
+; CHECK: [[CLEANUP]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %bb0
bb0: ; preds = %land.lhs.true, %entry
-;CHECK: bb0:
%x.tr = phi ptr [ %x, %entry ], [ null, %land.lhs.true ]
%0 = load i16, ptr %x.tr, align 4
-; CHECK: load i16, ptr
%conv = zext i16 %0 to i32
switch i32 %conv, label %if.end.50 [
- i32 43, label %cleanup
- i32 52, label %if.then.5
+ i32 43, label %cleanup
+ i32 52, label %if.then.5
]
if.then.5: ; preds = %bb0
@@ -36,8 +71,6 @@ if.then.26: ; preds = %if.then.5
br i1 undef, label %cond.end, label %cond.false
cond.false: ; preds = %if.then.26
-; CHECK: cond.false:
-; CHECK: load i16
%mode = getelementptr inbounds %struct.a, ptr %x.tr.lcssa163, i32 0, i32 1
%bf.load = load i16, ptr %mode, align 2
%bf.shl = shl i16 %bf.load, 8
@@ -50,7 +83,6 @@ if.then.44: ; preds = %cond.end
unreachable
if.end.50: ; preds = %bb0
-;%CHECK: if.end.50:
%conv.lcssa = phi i32 [ %conv, %bb0 ]
%arrayidx52 = getelementptr inbounds [0 x i32], ptr @length, i32 0, i32 %conv.lcssa
%1 = load i32, ptr %arrayidx52, align 4
@@ -68,7 +100,38 @@ cleanup: ; preds = %if.end.50, %cond.en
@dfg_text = external global ptr, align 4
define void @dfg_lex() {
-;CHECK-LABEL: dfg_lex
+; CHECK-LABEL: define void @dfg_lex() {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br label %[[WHILE_BODYTHREAD_PRE_SPLIT:.*]]
+; CHECK: [[WHILE_BODYTHREAD_PRE_SPLIT]]:
+; CHECK-NEXT: br i1 undef, label %[[WHILE_BODYTHREAD_PRE_SPLIT_IF_THEN_14_CRIT_EDGE:.*]], label %[[IF_END_15:.*]]
+; CHECK: [[WHILE_BODYTHREAD_PRE_SPLIT_IF_THEN_14_CRIT_EDGE]]:
+; CHECK-NEXT: [[V1_PRE:%.*]] = load i32, ptr @dfg_text, align 4
+; CHECK-NEXT: br label %[[IF_THEN_14:.*]]
+; CHECK: [[IF_THEN_14]]:
+; CHECK-NEXT: [[V1:%.*]] = phi i32 [ [[V1_PRE]], %[[WHILE_BODYTHREAD_PRE_SPLIT_IF_THEN_14_CRIT_EDGE]] ], [ [[SUB_PTR_RHS_CAST25:%.*]], %[[WHILE_END:.*]] ]
+; CHECK-NEXT: br label %[[IF_END_15]]
+; CHECK: [[IF_END_15]]:
+; CHECK-NEXT: [[V2:%.*]] = load ptr, ptr @yy_c_buf_p, align 4
+; CHECK-NEXT: br label %[[WHILE_COND_16:.*]]
+; CHECK: [[WHILE_COND_16]]:
+; CHECK-NEXT: br i1 undef, label %[[WHILE_COND_16]], label %[[WHILE_END]]
+; CHECK: [[WHILE_END]]:
+; CHECK-NEXT: [[ADD_PTR:%.*]] = getelementptr inbounds i8, ptr [[V2]], i32 undef
+; CHECK-NEXT: store ptr [[ADD_PTR]], ptr @dfg_text, align 4
+; CHECK-NEXT: [[SUB_PTR_RHS_CAST25]] = ptrtoint ptr [[ADD_PTR]] to i32
+; CHECK-NEXT: [[SUB_PTR_SUB26:%.*]] = sub i32 0, [[SUB_PTR_RHS_CAST25]]
+; CHECK-NEXT: switch i32 undef, label %[[SW_DEFAULT:.*]] [
+; CHECK-NEXT: i32 65, label %[[WHILE_BODYTHREAD_PRE_SPLIT]]
+; CHECK-NEXT: i32 3, label %[[RETURN:.*]]
+; CHECK-NEXT: i32 57, label %[[WHILE_BODYTHREAD_PRE_SPLIT]]
+; CHECK-NEXT: i32 60, label %[[IF_THEN_14]]
+; CHECK-NEXT: ]
+; CHECK: [[SW_DEFAULT]]:
+; CHECK-NEXT: unreachable
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: ret void
+;
entry:
br label %while.bodythread-pre-split
@@ -93,10 +156,10 @@ while.end: ; preds = %while.cond.16
%sub.ptr.rhs.cast25 = ptrtoint ptr %add.ptr to i32
%sub.ptr.sub26 = sub i32 0, %sub.ptr.rhs.cast25
switch i32 undef, label %sw.default [
- i32 65, label %while.bodythread-pre-split
- i32 3, label %return
- i32 57, label %while.bodythread-pre-split
- i32 60, label %if.then.14
+ i32 65, label %while.bodythread-pre-split
+ i32 3, label %return
+ i32 57, label %while.bodythread-pre-split
+ i32 60, label %if.then.14
]
sw.default: ; preds = %while.end
diff --git a/llvm/test/Transforms/GVN/pr28562.ll b/llvm/test/Transforms/GVN/pr28562.ll
index 338200af621fa8..86f2f0e0cc784a 100644
--- a/llvm/test/Transforms/GVN/pr28562.ll
+++ b/llvm/test/Transforms/GVN/pr28562.ll
@@ -1,9 +1,12 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -S -passes=gvn < %s | FileCheck %s
define ptr @test1(ptr %a) {
+; CHECK-LABEL: define ptr @test1(
+; CHECK-SAME: ptr [[A:%.*]]) {
+; CHECK-NEXT: [[X1:%.*]] = getelementptr i32, ptr [[A]], i32 10
+; CHECK-NEXT: ret ptr [[X1]]
+;
%x1 = getelementptr inbounds i32, ptr %a, i32 10
%x2 = getelementptr i32, ptr %a, i32 10
ret ptr %x2
-; CHECK-LABEL: @test1(
-; CHECK: %[[x:.*]] = getelementptr i32, ptr %a, i32 10
-; CHECK: ret ptr %[[x]]
}
diff --git a/llvm/test/Transforms/GVN/readattrs.ll b/llvm/test/Transforms/GVN/readattrs.ll
index b16c53adc0d4db..e62cbdac07a767 100644
--- a/llvm/test/Transforms/GVN/readattrs.ll
+++ b/llvm/test/Transforms/GVN/readattrs.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S -o - < %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"
@@ -6,12 +7,15 @@ target triple = "x86_64-unknown-linux-gnu"
declare void @use(ptr readonly nocapture)
define i8 @test() {
+; CHECK-LABEL: define i8 @test() {
+; CHECK-NEXT: [[A:%.*]] = alloca i8, align 1
+; CHECK-NEXT: store i8 1, ptr [[A]], align 1
+; CHECK-NEXT: call void @use(ptr [[A]])
+; CHECK-NEXT: ret i8 1
+;
%a = alloca i8
store i8 1, ptr %a
call void @use(ptr %a)
%b = load i8, ptr %a
ret i8 %b
-; CHECK-LABEL: define i8 @test(
-; CHECK: call void @use(ptr %a)
-; CHECK-NEXT: ret i8 1
}
diff --git a/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll b/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
index 8332a987ab9e32..ba5da942ec5c90 100644
--- a/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
+++ b/llvm/test/Transforms/GVN/simplify-icf-cache-invalidation.ll
@@ -1,6 +1,6 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
-; CHECK: define {{.*}}@eggs
%struct.zot = type { ptr }
%struct.wombat = type { ptr }
@@ -11,6 +11,28 @@
declare ptr @f()
define hidden void @eggs(ptr %arg, i1 %arg2, ptr %arg3, i32 %arg4, ptr %arg5) unnamed_addr align 2 {
+; CHECK-LABEL: define hidden void @eggs(
+; CHECK-SAME: ptr [[ARG:%.*]], i1 [[ARG2:%.*]], ptr [[ARG3:%.*]], i32 [[ARG4:%.*]], ptr [[ARG5:%.*]]) unnamed_addr align 2 {
+; CHECK-NEXT: [[BB:.*:]]
+; CHECK-NEXT: [[TMP:%.*]] = alloca [[STRUCT_WOMBAT:%.*]], align 8
+; CHECK-NEXT: store ptr @global, ptr [[ARG]], align 8, !invariant.group [[META0:![0-9]+]]
+; CHECK-NEXT: br i1 [[ARG2]], label %[[BB4:.*]], label %[[BB2:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: [[TMP3:%.*]] = atomicrmw sub ptr [[ARG3]], i32 [[ARG4]] acq_rel, align 4
+; CHECK-NEXT: br label %[[BB4]]
+; CHECK: [[BB4]]:
+; CHECK-NEXT: [[TMP5:%.*]] = load ptr, ptr [[ARG5]], align 8
+; CHECK-NEXT: [[TMP6:%.*]] = getelementptr inbounds [[STRUCT_BAZ:%.*]], ptr [[TMP5]], i64 0, i32 1
+; CHECK-NEXT: br i1 [[ARG2]], label %[[BB9:.*]], label %[[BB7:.*]]
+; CHECK: [[BB7]]:
+; CHECK-NEXT: [[TMP8:%.*]] = tail call ptr @f()
+; CHECK-NEXT: br label %[[BB9]]
+; CHECK: [[BB9]]:
+; CHECK-NEXT: tail call void @quux(ptr [[ARG]], i1 [[ARG2]])
+; CHECK-NEXT: [[TMP17:%.*]] = load ptr, ptr [[TMP]], align 8
+; CHECK-NEXT: [[TMP18:%.*]] = icmp eq ptr [[TMP17]], null
+; CHECK-NEXT: ret void
+;
bb:
%tmp = alloca %struct.wombat, align 8
store ptr @global, ptr %arg, align 8, !invariant.group !0
@@ -45,3 +67,6 @@ declare hidden void @quux(ptr, i1) unnamed_addr #0 align 2
attributes #0 = { nounwind willreturn }
!0 = !{}
+;.
+; CHECK: [[META0]] = !{}
+;.
diff --git a/llvm/test/Transforms/GVN/stale-loop-info.ll b/llvm/test/Transforms/GVN/stale-loop-info.ll
index 1d858c306673fb..7f1fab1ac31892 100644
--- a/llvm/test/Transforms/GVN/stale-loop-info.ll
+++ b/llvm/test/Transforms/GVN/stale-loop-info.ll
@@ -1,3 +1,4 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes='require<loops>,gvn' -S < %s | FileCheck %s
; This used to fail with ASAN enabled and if for some reason LoopInfo remained
@@ -14,6 +15,27 @@ target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128"
declare void @snork.1(ptr) local_unnamed_addr #0
define hidden zeroext i1 @eggs(ptr %arg, i1 %arg2) unnamed_addr align 2 {
+; CHECK-LABEL: define hidden zeroext i1 @eggs(
+; CHECK-SAME: ptr [[ARG:%.*]], i1 [[ARG2:%.*]]) unnamed_addr align 2 {
+; CHECK-NEXT: [[BB:.*:]]
+; CHECK-NEXT: br i1 [[ARG2]], label %[[BB14:.*]], label %[[BB3:.*]]
+; CHECK: [[BB3]]:
+; CHECK-NEXT: [[TMP:%.*]] = getelementptr inbounds [[STRUCT_WIBBLE_1028:%.*]], ptr [[ARG]], i64 0, i32 2, i32 0, i32 0, i64 0
+; CHECK-NEXT: br label %[[BB6:.*]]
+; CHECK: [[BB6]]:
+; CHECK-NEXT: br i1 undef, label %[[BB11:.*]], label %[[BB8:.*]]
+; CHECK: [[BB8]]:
+; CHECK-NEXT: [[TMP9:%.*]] = load ptr, ptr [[TMP]], align 8
+; CHECK-NEXT: br label %[[BB12:.*]]
+; CHECK: [[BB11]]:
+; CHECK-NEXT: br label %[[BB12]]
+; CHECK: [[BB12]]:
+; CHECK-NEXT: [[TMP13:%.*]] = phi ptr [ [[TMP]], %[[BB11]] ], [ [[TMP9]], %[[BB8]] ]
+; CHECK-NEXT: call void @snork.1(ptr [[TMP13]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: br label %[[BB6]]
+; CHECK: [[BB14]]:
+; CHECK-NEXT: ret i1 false
+;
bb:
br i1 %arg2, label %bb14, label %bb3
@@ -29,7 +51,6 @@ bb7: ; preds = %bb6
bb8: ; preds = %bb7
%tmp9 = load ptr, ptr %tmp, align 8
-; CHECK: %tmp9 = load ptr, ptr %tmp, align 8
br label %bb12
bb11: ; preds = %bb7
diff --git a/llvm/test/Transforms/GVN/tbaa.ll b/llvm/test/Transforms/GVN/tbaa.ll
index 46d1bb737a6934..7d1630d7a818e9 100644
--- a/llvm/test/Transforms/GVN/tbaa.ll
+++ b/llvm/test/Transforms/GVN/tbaa.ll
@@ -1,10 +1,13 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt -passes=gvn -S < %s | FileCheck %s
define i32 @test1(ptr %p, ptr %q) {
-; CHECK-LABEL: @test1(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p)
-; CHECK-NOT: tbaa
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test1(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]])
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p)
%c = add i32 %a, %b
@@ -12,9 +15,12 @@ define i32 @test1(ptr %p, ptr %q) {
}
define i32 @test2(ptr %p, ptr %q) {
-; CHECK-LABEL: @test2(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p), !tbaa [[TAGC:!.*]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test2(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA0:![0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p), !tbaa !0
%c = add i32 %a, %b
@@ -22,9 +28,12 @@ define i32 @test2(ptr %p, ptr %q) {
}
define i32 @test3(ptr %p, ptr %q) {
-; CHECK-LABEL: @test3(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p), !tbaa [[TAGB:!.*]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test3(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA4:![0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !3
%b = call i32 @foo(ptr %p), !tbaa !3
%c = add i32 %a, %b
@@ -32,9 +41,12 @@ define i32 @test3(ptr %p, ptr %q) {
}
define i32 @test4(ptr %p, ptr %q) {
-; CHECK-LABEL: @test4(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p), !tbaa [[TAGA:!.*]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test4(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6:![0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !1
%b = call i32 @foo(ptr %p), !tbaa !0
%c = add i32 %a, %b
@@ -42,9 +54,12 @@ define i32 @test4(ptr %p, ptr %q) {
}
define i32 @test5(ptr %p, ptr %q) {
-; CHECK-LABEL: @test5(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p), !tbaa [[TAGA]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test5(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p), !tbaa !1
%c = add i32 %a, %b
@@ -52,9 +67,12 @@ define i32 @test5(ptr %p, ptr %q) {
}
define i32 @test6(ptr %p, ptr %q) {
-; CHECK-LABEL: @test6(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p), !tbaa [[TAGA]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test6(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA6]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !0
%b = call i32 @foo(ptr %p), !tbaa !3
%c = add i32 %a, %b
@@ -62,10 +80,12 @@ define i32 @test6(ptr %p, ptr %q) {
}
define i32 @test7(ptr %p, ptr %q) {
-; CHECK-LABEL: @test7(ptr %p, ptr %q)
-; CHECK: call i32 @foo(ptr %p)
-; CHECK-NOT: tbaa
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test7(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]])
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !4
%b = call i32 @foo(ptr %p), !tbaa !3
%c = add i32 %a, %b
@@ -73,9 +93,11 @@ define i32 @test7(ptr %p, ptr %q) {
}
define i32 @test8(ptr %p, ptr %q) {
-; CHECK-LABEL: @test8
-; CHECK-NEXT: store i32 15, ptr %p
-; CHECK-NEXT: ret i32 0
+; CHECK-LABEL: define i32 @test8(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: store i32 15, ptr [[P]], align 4
+; CHECK-NEXT: ret i32 0
+;
; Since we know the location is invariant, we can forward the
; load across the potentially aliasing store.
@@ -87,9 +109,11 @@ define i32 @test8(ptr %p, ptr %q) {
}
define i32 @test9(ptr %p, ptr %q) {
-; CHECK-LABEL: @test9
-; CHECK-NEXT: call void @clobber()
-; CHECK-NEXT: ret i32 0
+; CHECK-LABEL: define i32 @test9(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: call void @clobber()
+; CHECK-NEXT: ret i32 0
+;
; Since we know the location is invariant, we can forward the
; load across the potentially aliasing store (within the call).
@@ -103,9 +127,12 @@ define i32 @test9(ptr %p, ptr %q) {
define i32 @test10(ptr %p, ptr %q) {
; If one access encloses the other, then the merged access is the enclosed one
; and not just the common final access type.
-; CHECK-LABEL: @test10
-; CHECK: call i32 @foo(ptr %p), !tbaa [[TAG_X_i:!.*]]
-; CHECK: %c = add i32 %a, %a
+; CHECK-LABEL: define i32 @test10(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]]) {
+; CHECK-NEXT: [[A:%.*]] = call i32 @foo(ptr [[P]]), !tbaa [[TBAA7:![0-9]+]]
+; CHECK-NEXT: [[C:%.*]] = add i32 [[A]], [[A]]
+; CHECK-NEXT: ret i32 [[C]]
+;
%a = call i32 @foo(ptr %p), !tbaa !15 ; TAG_X_i
%b = call i32 @foo(ptr %p), !tbaa !19 ; TAG_Y_x_i
%c = add i32 %a, %b
@@ -115,12 +142,6 @@ define i32 @test10(ptr %p, ptr %q) {
declare void @clobber()
declare i32 @foo(ptr) readonly
-; CHECK-DAG: [[TAGC]] = !{[[TYPEC:!.*]], [[TYPEC]], i64 0}
-; CHECK-DAG: [[TYPEC]] = !{!"C", [[TYPEA:!.*]]}
-; CHECK-DAG: [[TYPEA]] = !{!"A", !{{.*}}}
-; CHECK-DAG: [[TAGB]] = !{[[TYPEB:!.*]], [[TYPEB]], i64 0}
-; CHECK-DAG: [[TYPEB]] = !{!"B", [[TYPEA]]}
-; CHECK-DAG: [[TAGA]] = !{[[TYPEA]], [[TYPEA]], i64 0}
!0 = !{!5, !5, i64 0}
!1 = !{!6, !6, i64 0}
!2 = !{!"tbaa root"}
@@ -132,9 +153,6 @@ declare i32 @foo(ptr) readonly
!8 = !{!"another root"}
!11 = !{!"scalar type", !8}
-; CHECK-DAG: [[TAG_X_i]] = !{[[TYPE_X:!.*]], [[TYPE_int:!.*]], i64 0}
-; CHECK-DAG: [[TYPE_X:!.*]] = !{!"struct X", [[TYPE_int]], i64 0}
-; CHECK-DAG: [[TYPE_int]] = !{!"int", {{!.*}}, i64 0}
!15 = !{!16, !17, i64 0} ; TAG_X_i
!16 = !{!"struct X", !17, i64 0} ; struct X { int i; };
!17 = !{!"int", !18, i64 0}
@@ -146,3 +164,16 @@ declare i32 @foo(ptr) readonly
; A TBAA structure who's only point is to have a constant location.
!9 = !{!"yet another root"}
!10 = !{!"node", !9, i64 1}
+;.
+; CHECK: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
+; CHECK: [[META1]] = !{!"C", [[META2:![0-9]+]]}
+; CHECK: [[META2]] = !{!"A", [[META3:![0-9]+]]}
+; CHECK: [[META3]] = !{!"tbaa root"}
+; CHECK: [[TBAA4]] = !{[[META5:![0-9]+]], [[META5]], i64 0}
+; CHECK: [[META5]] = !{!"B", [[META2]]}
+; CHECK: [[TBAA6]] = !{[[META2]], [[META2]], i64 0}
+; CHECK: [[TBAA7]] = !{[[META8:![0-9]+]], [[META9:![0-9]+]], i64 0}
+; CHECK: [[META8]] = !{!"struct X", [[META9]], i64 0}
+; CHECK: [[META9]] = !{!"int", [[META10:![0-9]+]], i64 0}
+; CHECK: [[META10]] = !{!"char", [[META3]], i64 0}
+;.
diff --git a/llvm/test/Transforms/GVN/unreachable-predecessor.ll b/llvm/test/Transforms/GVN/unreachable-predecessor.ll
index 532d55458d5d55..5c667049ef387b 100644
--- a/llvm/test/Transforms/GVN/unreachable-predecessor.ll
+++ b/llvm/test/Transforms/GVN/unreachable-predecessor.ll
@@ -1,13 +1,32 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
; RUN: opt < %s -passes=gvn -S | FileCheck %s
; loop.then is not reachable from loop, so we should be able to deduce that the
; store through %phi2 cannot alias %ptr1.
-; CHECK-LABEL: @test1
define void @test1(ptr %ptr1, ptr %ptr2) {
-; CHECK-LABEL: entry:
-; CHECK: %[[GEP:.*]] = getelementptr inbounds i32, ptr %ptr1, i64 1
-; CHECK: %[[VAL1:.*]] = load i32, ptr %[[GEP]]
+; CHECK-LABEL: define void @test1(
+; CHECK-SAME: ptr [[PTR1:%.*]], ptr [[PTR2:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: [[GEP1:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i64 1
+; CHECK-NEXT: [[VAL1_PRE:%.*]] = load i32, ptr [[GEP1]], align 4
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[PHI1:%.*]] = phi ptr [ [[GEP1]], %[[ENTRY]] ], [ [[PHI2:%.*]], %[[LOOP_THEN:.*]] ]
+; CHECK-NEXT: br i1 false, label %[[LOOP_LOOP_THEN_CRIT_EDGE:.*]], label %[[LOOP_IF:.*]]
+; CHECK: [[LOOP_LOOP_THEN_CRIT_EDGE]]:
+; CHECK-NEXT: br label %[[LOOP_THEN]]
+; CHECK: [[LOOP_IF]]:
+; CHECK-NEXT: [[GEP2:%.*]] = getelementptr inbounds i32, ptr [[GEP1]], i64 1
+; CHECK-NEXT: [[VAL2:%.*]] = load i32, ptr [[GEP2]], align 4
+; CHECK-NEXT: [[CMP:%.*]] = icmp slt i32 [[VAL1_PRE]], [[VAL2]]
+; CHECK-NEXT: br label %[[LOOP_THEN]]
+; CHECK: [[LOOP_THEN]]:
+; CHECK-NEXT: [[PHI2]] = phi ptr [ poison, %[[LOOP_LOOP_THEN_CRIT_EDGE]] ], [ [[GEP2]], %[[LOOP_IF]] ]
+; CHECK-NEXT: store i32 [[VAL1_PRE]], ptr [[PHI2]], align 4
+; CHECK-NEXT: store i32 0, ptr [[PTR1]], align 4
+; CHECK-NEXT: br label %[[LOOP]]
+;
entry:
br label %loop.preheader
@@ -15,8 +34,6 @@ loop.preheader:
%gep1 = getelementptr inbounds i32, ptr %ptr1, i64 1
br label %loop
-; CHECK-LABEL: loop:
-; CHECK-NOT: load
loop:
%phi1 = phi ptr [ %gep1, %loop.preheader ], [ %phi2, %loop.then ]
%val1 = load i32, ptr %phi1
@@ -28,8 +45,6 @@ loop.if:
%cmp = icmp slt i32 %val1, %val2
br label %loop.then
-; CHECK-LABEL: loop.then
-; CHECK: store i32 %[[VAL1]], ptr %phi2
loop.then:
%phi2 = phi ptr [ %ptr2, %loop ], [ %gep2, %loop.if ]
store i32 %val1, ptr %phi2
More information about the llvm-commits
mailing list