[llvm] [GVN-PRE][Tests] Add MSSA coverage to some more tests [4/N] (PR #151919)
Madhur Amilkanthwar via llvm-commits
llvm-commits at lists.llvm.org
Mon Aug 4 01:43:08 PDT 2025
https://github.com/madhur13490 created https://github.com/llvm/llvm-project/pull/151919
This should be the final PR for tests under PRE.
>From 7042ef553db7f3810cc79ad32bad3383f06c029a Mon Sep 17 00:00:00 2001
From: Madhur Amilkanthwar <madhura at nvidia.com>
Date: Mon, 28 Jul 2025 07:37:20 -0700
Subject: [PATCH] [GVN-PRE][Tests] Add MSSA coverage to some more tests
---
.../Transforms/GVN/PRE/phi-translate-2.ll | 198 ++-
.../Transforms/GVN/PRE/phi-translate-add.ll | 45 +-
llvm/test/Transforms/GVN/PRE/phi-translate.ll | 87 +-
.../Transforms/GVN/PRE/pre-aliasning-path.ll | 61 +-
llvm/test/Transforms/GVN/PRE/pre-basic-add.ll | 52 +-
llvm/test/Transforms/GVN/PRE/pre-jt-add.ll | 30 +-
llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll | 187 ++-
.../Transforms/GVN/PRE/pre-load-guards.ll | 139 ++-
.../GVN/PRE/pre-load-implicit-cf-updates.ll | 112 +-
llvm/test/Transforms/GVN/PRE/pre-load.ll | 1089 +++++++++++------
.../GVN/PRE/pre-loop-load-new-pm.ll | 12 +-
.../Transforms/GVN/PRE/pre-no-cost-phi.ll | 25 +-
.../test/Transforms/GVN/PRE/pre-poison-add.ll | 83 +-
.../Transforms/GVN/PRE/pre-single-pred.ll | 90 +-
llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll | 53 +-
15 files changed, 1594 insertions(+), 669 deletions(-)
diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll b/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll
index a38d3e50a6121..1e789b0613f4f 100644
--- a/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll
+++ b/llvm/test/Transforms/GVN/PRE/phi-translate-2.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=gvn -S | FileCheck %s
+; RUN: opt < %s -passes=gvn -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -S | FileCheck %s --check-prefixes=CHECK,MSSA
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@a = common global [100 x i64] zeroinitializer, align 16
@@ -50,32 +51,56 @@ if.end: ; preds = %if.then, %entry
}
define void @test2(i64 %i) {
-; CHECK-LABEL: @test2(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I:%.*]]
-; CHECK-NEXT: [[T0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I]]
-; CHECK-NEXT: [[T1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
-; CHECK-NEXT: [[MUL:%.*]] = mul nsw i64 [[T1]], [[T0]]
-; CHECK-NEXT: store i64 [[MUL]], ptr @g1, align 8
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MUL]], 3
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo()
-; CHECK-NEXT: store i64 [[CALL]], ptr @g2, align 8
-; CHECK-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @a, i64 24), align 8
-; CHECK-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @b, i64 24), align 8
-; CHECK-NEXT: [[DOTPRE:%.*]] = mul nsw i64 [[T3_PRE]], [[T2_PRE]]
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: [[MUL5_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], [[IF_THEN]] ], [ [[MUL]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: [[T3:%.*]] = phi i64 [ [[T3_PRE]], [[IF_THEN]] ], [ [[T1]], [[ENTRY]] ]
-; CHECK-NEXT: [[T2:%.*]] = phi i64 [ [[T2_PRE]], [[IF_THEN]] ], [ [[T0]], [[ENTRY]] ]
-; CHECK-NEXT: [[I_ADDR_0:%.*]] = phi i64 [ 3, [[IF_THEN]] ], [ [[I]], [[ENTRY]] ]
-; CHECK-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I_ADDR_0]]
-; CHECK-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I_ADDR_0]]
-; CHECK-NEXT: store i64 [[MUL5_PRE_PHI]], ptr @g3, align 8
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test2(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I:%.*]]
+; MDEP-NEXT: [[T0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
+; MDEP-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I]]
+; MDEP-NEXT: [[T1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
+; MDEP-NEXT: [[MUL:%.*]] = mul nsw i64 [[T1]], [[T0]]
+; MDEP-NEXT: store i64 [[MUL]], ptr @g1, align 8
+; MDEP-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MUL]], 3
+; MDEP-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo()
+; MDEP-NEXT: store i64 [[CALL]], ptr @g2, align 8
+; MDEP-NEXT: [[T2_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @a, i64 24), align 8
+; MDEP-NEXT: [[T3_PRE:%.*]] = load i64, ptr getelementptr inbounds nuw (i8, ptr @b, i64 24), align 8
+; MDEP-NEXT: [[DOTPRE:%.*]] = mul nsw i64 [[T3_PRE]], [[T2_PRE]]
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: [[MUL5_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], [[IF_THEN]] ], [ [[MUL]], [[ENTRY:%.*]] ]
+; MDEP-NEXT: [[T3:%.*]] = phi i64 [ [[T3_PRE]], [[IF_THEN]] ], [ [[T1]], [[ENTRY]] ]
+; MDEP-NEXT: [[T2:%.*]] = phi i64 [ [[T2_PRE]], [[IF_THEN]] ], [ [[T0]], [[ENTRY]] ]
+; MDEP-NEXT: [[I_ADDR_0:%.*]] = phi i64 [ 3, [[IF_THEN]] ], [ [[I]], [[ENTRY]] ]
+; MDEP-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I_ADDR_0]]
+; MDEP-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I_ADDR_0]]
+; MDEP-NEXT: store i64 [[MUL5_PRE_PHI]], ptr @g3, align 8
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test2(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I:%.*]]
+; MSSA-NEXT: [[T0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8
+; MSSA-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I]]
+; MSSA-NEXT: [[T1:%.*]] = load i64, ptr [[ARRAYIDX1]], align 8
+; MSSA-NEXT: [[MUL:%.*]] = mul nsw i64 [[T1]], [[T0]]
+; MSSA-NEXT: store i64 [[MUL]], ptr @g1, align 8
+; MSSA-NEXT: [[CMP:%.*]] = icmp sgt i64 [[MUL]], 3
+; MSSA-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[CALL:%.*]] = tail call i64 (...) @goo()
+; MSSA-NEXT: store i64 [[CALL]], ptr @g2, align 8
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: [[I_ADDR_0:%.*]] = phi i64 [ 3, [[IF_THEN]] ], [ [[I]], [[ENTRY:%.*]] ]
+; MSSA-NEXT: [[ARRAYIDX3:%.*]] = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 [[I_ADDR_0]]
+; MSSA-NEXT: [[T2:%.*]] = load i64, ptr [[ARRAYIDX3]], align 8
+; MSSA-NEXT: [[ARRAYIDX4:%.*]] = getelementptr inbounds [100 x i64], ptr @b, i64 0, i64 [[I_ADDR_0]]
+; MSSA-NEXT: [[T3:%.*]] = load i64, ptr [[ARRAYIDX4]], align 8
+; MSSA-NEXT: [[MUL5:%.*]] = mul nsw i64 [[T3]], [[T2]]
+; MSSA-NEXT: store i64 [[MUL5]], ptr @g3, align 8
+; MSSA-NEXT: ret void
;
entry:
%arrayidx = getelementptr inbounds [100 x i64], ptr @a, i64 0, i64 %i
@@ -252,29 +277,50 @@ if.end3: ; preds = %if.then2, %if.else,
; available in if.then. Check that we correctly phi-translate to the phi that
; the load has been replaced with.
define void @test6(ptr %ptr, i1 %arg) {
-; CHECK-LABEL: @test6(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[ARRAYIDX1_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
-; CHECK-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX1_PHI_TRANS_INSERT]], align 4
-; CHECK-NEXT: br label [[WHILE:%.*]]
-; CHECK: while:
-; CHECK-NEXT: [[TMP0:%.*]] = phi i32 [ [[DOTPRE]], [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[IF_END:%.*]] ]
-; CHECK-NEXT: [[I:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[IF_END]] ]
-; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]]
-; CHECK-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
-; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I_NEXT]]
-; CHECK-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
-; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
-; CHECK-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX1]], align 4
-; CHECK-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: [[TMP2]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[WHILE]] ]
-; CHECK-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]]
-; CHECK: while.end:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test6(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[ARRAYIDX1_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 1
+; MDEP-NEXT: [[DOTPRE:%.*]] = load i32, ptr [[ARRAYIDX1_PHI_TRANS_INSERT]], align 4
+; MDEP-NEXT: br label [[WHILE:%.*]]
+; MDEP: while:
+; MDEP-NEXT: [[TMP0:%.*]] = phi i32 [ [[DOTPRE]], [[ENTRY:%.*]] ], [ [[TMP2:%.*]], [[IF_END:%.*]] ]
+; MDEP-NEXT: [[I:%.*]] = phi i64 [ 1, [[ENTRY]] ], [ [[I_NEXT:%.*]], [[IF_END]] ]
+; MDEP-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I]]
+; MDEP-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; MDEP-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I_NEXT]]
+; MDEP-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
+; MDEP-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
+; MDEP-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]
+; MDEP: if.then:
+; MDEP-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX1]], align 4
+; MDEP-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: [[TMP2]] = phi i32 [ [[TMP0]], [[IF_THEN]] ], [ [[TMP1]], [[WHILE]] ]
+; MDEP-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]]
+; MDEP: while.end:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test6(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: br label [[WHILE:%.*]]
+; MSSA: while:
+; MSSA-NEXT: [[I:%.*]] = phi i64 [ 1, [[ENTRY:%.*]] ], [ [[I_NEXT:%.*]], [[IF_END:%.*]] ]
+; MSSA-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i32, ptr [[PTR:%.*]], i64 [[I]]
+; MSSA-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX1]], align 4
+; MSSA-NEXT: [[I_NEXT]] = add nuw nsw i64 [[I]], 1
+; MSSA-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR]], i64 [[I_NEXT]]
+; MSSA-NEXT: [[TMP1:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
+; MSSA-NEXT: [[CMP:%.*]] = icmp sgt i32 [[TMP0]], [[TMP1]]
+; MSSA-NEXT: br i1 [[CMP]], label [[IF_THEN:%.*]], label [[IF_END]]
+; MSSA: if.then:
+; MSSA-NEXT: store i32 [[TMP1]], ptr [[ARRAYIDX1]], align 4
+; MSSA-NEXT: store i32 [[TMP0]], ptr [[ARRAYIDX2]], align 4
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: br i1 [[ARG:%.*]], label [[WHILE_END:%.*]], label [[WHILE]]
+; MSSA: while.end:
+; MSSA-NEXT: ret void
;
entry:
br label %while
@@ -304,24 +350,40 @@ while.end:
; Load from arrayidx2 is partially redundant, check that address translation can
; fold sext + trunc across phi node together.
define i32 @test7(ptr noalias %ptr1, ptr noalias %ptr2, i32 %i, i1 %cond) {
-; CHECK-LABEL: @test7(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]]
-; CHECK: entry.if.end_crit_edge:
-; CHECK-NEXT: [[RES_PRE:%.*]] = load i32, ptr [[PTR1:%.*]], align 4
-; CHECK-NEXT: br label [[IF_END:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[I:%.*]]
-; CHECK-NEXT: [[TMP:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
-; CHECK-NEXT: store i32 [[TMP]], ptr [[PTR2:%.*]], align 4
-; CHECK-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I]] to i64
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: [[RES:%.*]] = phi i32 [ [[RES_PRE]], [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[TMP]], [[IF_THEN]] ]
-; CHECK-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[IDX_EXT]], [[IF_THEN]] ]
-; CHECK-NEXT: [[IDX_TRUNC:%.*]] = trunc i64 [[IDX]] to i32
-; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[IDX_TRUNC]]
-; CHECK-NEXT: ret i32 [[RES]]
+; MDEP-LABEL: @test7(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[ENTRY_IF_END_CRIT_EDGE:%.*]]
+; MDEP: entry.if.end_crit_edge:
+; MDEP-NEXT: [[RES_PRE:%.*]] = load i32, ptr [[PTR1:%.*]], align 4
+; MDEP-NEXT: br label [[IF_END:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[I:%.*]]
+; MDEP-NEXT: [[TMP:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; MDEP-NEXT: store i32 [[TMP]], ptr [[PTR2:%.*]], align 4
+; MDEP-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I]] to i64
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: [[RES:%.*]] = phi i32 [ [[RES_PRE]], [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[TMP]], [[IF_THEN]] ]
+; MDEP-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY_IF_END_CRIT_EDGE]] ], [ [[IDX_EXT]], [[IF_THEN]] ]
+; MDEP-NEXT: [[IDX_TRUNC:%.*]] = trunc i64 [[IDX]] to i32
+; MDEP-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[IDX_TRUNC]]
+; MDEP-NEXT: ret i32 [[RES]]
+;
+; MSSA-LABEL: @test7(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_END:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr [[PTR1:%.*]], i32 [[I:%.*]]
+; MSSA-NEXT: [[TMP:%.*]] = load i32, ptr [[ARRAYIDX]], align 4
+; MSSA-NEXT: store i32 [[TMP]], ptr [[PTR2:%.*]], align 4
+; MSSA-NEXT: [[IDX_EXT:%.*]] = sext i32 [[I]] to i64
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: [[IDX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IDX_EXT]], [[IF_THEN]] ]
+; MSSA-NEXT: [[IDX_TRUNC:%.*]] = trunc i64 [[IDX]] to i32
+; MSSA-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds i32, ptr [[PTR1]], i32 [[IDX_TRUNC]]
+; MSSA-NEXT: [[RES:%.*]] = load i32, ptr [[ARRAYIDX2]], align 4
+; MSSA-NEXT: ret i32 [[RES]]
;
entry:
br i1 %cond, label %if.then, label %if.end
diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll b/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll
index ea43307649572..cb05a8ed384ce 100644
--- a/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll
+++ b/llvm/test/Transforms/GVN/PRE/phi-translate-add.ll
@@ -1,21 +1,35 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -passes=gvn -gvn-add-phi-translation=true -S < %s | FileCheck %s --check-prefix=ADD-TRANS-ON
-; RUN: opt -passes=gvn -gvn-add-phi-translation=false -S < %s | FileCheck %s --check-prefix=ADD-TRANS-OFF
+; RUN: opt -passes=gvn -gvn-add-phi-translation=true -S < %s | FileCheck %s --check-prefix=ADD-TRANS-ON --check-prefixes=CHECK,PT-ON-MDEP
+; RUN: opt -passes='gvn<memoryssa>' -gvn-add-phi-translation=true -S < %s | FileCheck %s --check-prefix=ADD-TRANS-ON --check-prefixes=CHECK,PT-ON-MSSA
+; RUN: opt -passes=gvn -gvn-add-phi-translation=false -S < %s | FileCheck %s --check-prefix=ADD-TRANS-OFF --check-prefixes=CHECK,PT-OFF-MDEP
+; RUN: opt -passes='gvn<memoryssa>' -gvn-add-phi-translation=false -S < %s | FileCheck %s --check-prefix=ADD-TRANS-OFF --check-prefixes=CHECK,PT-OFF-MSSA
; Test that phi translation is able to hoist a load whose address
; depends on an add also being hoisted.
define double @phi_translation_hoists_add(ptr %a, i64 %idx) {
-; ADD-TRANS-ON-LABEL: @phi_translation_hoists_add(
-; ADD-TRANS-ON-NEXT: entry:
-; ADD-TRANS-ON-NEXT: [[ADD_PHI_TRANS_INSERT:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1
-; ADD-TRANS-ON-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[ADD_PHI_TRANS_INSERT]]
-; ADD-TRANS-ON-NEXT: [[LOAD_PRE:%.*]] = load double, ptr [[GEP_PHI_TRANS_INSERT]], align 8
-; ADD-TRANS-ON-NEXT: br label [[FOR_BODY:%.*]]
-; ADD-TRANS-ON: for.body:
-; ADD-TRANS-ON-NEXT: [[CMP:%.*]] = fcmp ole double [[LOAD_PRE]], 1.000000e+00
-; ADD-TRANS-ON-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[FOR_BODY]]
-; ADD-TRANS-ON: exit:
-; ADD-TRANS-ON-NEXT: ret double [[LOAD_PRE]]
+; PT-ON-MDEP-LABEL: @phi_translation_hoists_add(
+; PT-ON-MDEP-NEXT: entry:
+; PT-ON-MDEP-NEXT: [[ADD_PHI_TRANS_INSERT:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1
+; PT-ON-MDEP-NEXT: [[GEP_PHI_TRANS_INSERT:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[ADD_PHI_TRANS_INSERT]]
+; PT-ON-MDEP-NEXT: [[LOAD_PRE:%.*]] = load double, ptr [[GEP_PHI_TRANS_INSERT]], align 8
+; PT-ON-MDEP-NEXT: br label [[FOR_BODY:%.*]]
+; PT-ON-MDEP: for.body:
+; PT-ON-MDEP-NEXT: [[CMP:%.*]] = fcmp ole double [[LOAD_PRE]], 1.000000e+00
+; PT-ON-MDEP-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[FOR_BODY]]
+; PT-ON-MDEP: exit:
+; PT-ON-MDEP-NEXT: ret double [[LOAD_PRE]]
+;
+; PT-ON-MSSA-LABEL: @phi_translation_hoists_add(
+; PT-ON-MSSA-NEXT: entry:
+; PT-ON-MSSA-NEXT: br label [[FOR_BODY:%.*]]
+; PT-ON-MSSA: for.body:
+; PT-ON-MSSA-NEXT: [[ADD:%.*]] = add nuw nsw i64 [[IDX:%.*]], 1
+; PT-ON-MSSA-NEXT: [[GEP:%.*]] = getelementptr inbounds double, ptr [[A:%.*]], i64 [[ADD]]
+; PT-ON-MSSA-NEXT: [[LOAD:%.*]] = load double, ptr [[GEP]], align 8
+; PT-ON-MSSA-NEXT: [[CMP:%.*]] = fcmp ole double [[LOAD]], 1.000000e+00
+; PT-ON-MSSA-NEXT: br i1 [[CMP]], label [[EXIT:%.*]], label [[FOR_BODY]]
+; PT-ON-MSSA: exit:
+; PT-ON-MSSA-NEXT: ret double [[LOAD]]
;
; ADD-TRANS-OFF-LABEL: @phi_translation_hoists_add(
; ADD-TRANS-OFF-NEXT: entry:
@@ -42,3 +56,8 @@ for.body: ; preds = %for.body, %entry
exit:
ret double %load
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; ADD-TRANS-ON: {{.*}}
+; CHECK: {{.*}}
+; PT-OFF-MDEP: {{.*}}
+; PT-OFF-MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/phi-translate.ll b/llvm/test/Transforms/GVN/PRE/phi-translate.ll
index 713f012583403..084c449879b16 100644
--- a/llvm/test/Transforms/GVN/PRE/phi-translate.ll
+++ b/llvm/test/Transforms/GVN/PRE/phi-translate.ll
@@ -1,23 +1,53 @@
-; RUN: opt -passes=gvn -S < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=gvn -S < %s | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt -passes='gvn<memoryssa>' -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA
target datalayout = "e-p:64:64:64"
-; CHECK-LABEL: @foo(
-; CHECK: entry.end_crit_edge:
-; CHECK: %[[INDEX:[a-z0-9.]+]] = sext i32 %x to i64{{$}}
-; CHECK: %[[ADDRESS:[a-z0-9.]+]] = getelementptr [100 x i32], ptr @G, i64 0, i64 %[[INDEX]]{{$}}
-; CHECK: %n.pre = load i32, ptr %[[ADDRESS]], align 4, !dbg [[N_LOC:![0-9]+]]
-; CHECK: br label %end
-; CHECK: then:
-; CHECK: store i32 %z
-; CHECK: end:
-; CHECK: %n = phi i32 [ %n.pre, %entry.end_crit_edge ], [ %z, %then ], !dbg [[N_LOC]]
-; CHECK: ret i32 %n
-; CHECK: [[N_LOC]] = !DILocation(line: 47, column: 1, scope: !{{.*}})
@G = external global [100 x i32]
define i32 @foo(i32 %x, i32 %z) !dbg !6 {
+; MDEP-LABEL: define i32 @foo(
+; MDEP-SAME: i32 [[X:%.*]], i32 [[Z:%.*]]) !dbg [[DBG5:![0-9]+]] {
+; MDEP-NEXT: [[ENTRY:.*:]]
+; MDEP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[Z]], 0, !dbg [[DBG8:![0-9]+]]
+; MDEP-NEXT: br i1 [[TOBOOL]], label %[[ENTRY_END_CRIT_EDGE:.*]], label %[[THEN:.*]], !dbg [[DBG8]]
+; MDEP: [[ENTRY_END_CRIT_EDGE]]:
+; MDEP-NEXT: [[J_PHI_TRANS_INSERT:%.*]] = sext i32 [[X]] to i64
+; MDEP-NEXT: [[Q_PHI_TRANS_INSERT:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PHI_TRANS_INSERT]]
+; MDEP-NEXT: [[N_PRE:%.*]] = load i32, ptr [[Q_PHI_TRANS_INSERT]], align 4, !dbg [[DBG9:![0-9]+]]
+; MDEP-NEXT: br label %[[END:.*]], !dbg [[DBG8]]
+; MDEP: [[THEN]]:
+; MDEP-NEXT: [[I:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG10:![0-9]+]]
+; MDEP-NEXT: [[P:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[I]], !dbg [[DBG10]]
+; MDEP-NEXT: store i32 [[Z]], ptr [[P]], align 4, !dbg [[DBG10]]
+; MDEP-NEXT: br label %[[END]], !dbg [[DBG10]]
+; MDEP: [[END]]:
+; MDEP-NEXT: [[J_PRE_PHI:%.*]] = phi i64 [ [[J_PHI_TRANS_INSERT]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[I]], %[[THEN]] ], !dbg [[DBG11:![0-9]+]]
+; MDEP-NEXT: [[N:%.*]] = phi i32 [ [[N_PRE]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[Z]], %[[THEN]] ], !dbg [[DBG9]]
+; MDEP-NEXT: [[Q:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PRE_PHI]], !dbg [[DBG12:![0-9]+]]
+; MDEP-NEXT: ret i32 [[N]], !dbg [[DBG9]]
+;
+; MSSA-LABEL: define i32 @foo(
+; MSSA-SAME: i32 [[X:%.*]], i32 [[Z:%.*]]) !dbg [[DBG5:![0-9]+]] {
+; MSSA-NEXT: [[ENTRY:.*:]]
+; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[Z]], 0, !dbg [[DBG8:![0-9]+]]
+; MSSA-NEXT: br i1 [[TOBOOL]], label %[[ENTRY_END_CRIT_EDGE:.*]], label %[[THEN:.*]], !dbg [[DBG8]]
+; MSSA: [[ENTRY_END_CRIT_EDGE]]:
+; MSSA-NEXT: [[DOTPRE:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG9:![0-9]+]]
+; MSSA-NEXT: br label %[[END:.*]], !dbg [[DBG8]]
+; MSSA: [[THEN]]:
+; MSSA-NEXT: [[I:%.*]] = sext i32 [[X]] to i64, !dbg [[DBG10:![0-9]+]]
+; MSSA-NEXT: [[P:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[I]], !dbg [[DBG10]]
+; MSSA-NEXT: store i32 [[Z]], ptr [[P]], align 4, !dbg [[DBG10]]
+; MSSA-NEXT: br label %[[END]], !dbg [[DBG10]]
+; MSSA: [[END]]:
+; MSSA-NEXT: [[J_PRE_PHI:%.*]] = phi i64 [ [[DOTPRE]], %[[ENTRY_END_CRIT_EDGE]] ], [ [[I]], %[[THEN]] ], !dbg [[DBG9]]
+; MSSA-NEXT: [[Q:%.*]] = getelementptr [100 x i32], ptr @G, i64 0, i64 [[J_PRE_PHI]], !dbg [[DBG11:![0-9]+]]
+; MSSA-NEXT: [[N:%.*]] = load i32, ptr [[Q]], align 4, !dbg [[DBG12:![0-9]+]]
+; MSSA-NEXT: ret i32 [[N]], !dbg [[DBG12]]
+;
entry:
%tobool = icmp eq i32 %z, 0, !dbg !7
br i1 %tobool, label %end, label %then, !dbg !7
@@ -51,6 +81,31 @@ end:
!10 = !DILocation(line: 46, column: 1, scope: !6)
!11 = !DILocation(line: 47, column: 1, scope: !6)
!12 = distinct !DICompileUnit(language: DW_LANG_C99, producer: "clang",
- file: !5,
- isOptimized: true, flags: "-O2",
- splitDebugFilename: "abc.debug", emissionKind: 2)
+ file: !5,
+ isOptimized: true, flags: "-O2",
+ splitDebugFilename: "abc.debug", emissionKind: 2)
+;.
+; MDEP: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META4:![0-9]+]], producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly)
+; MDEP: [[META4]] = !DIFile(filename: "{{.*}}a.cc", directory: {{.*}})
+; MDEP: [[DBG5]] = distinct !DISubprogram(name: "foo", scope: [[META4]], file: [[META4]], line: 42, type: [[META6:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META3]], retainedNodes: [[META7:![0-9]+]])
+; MDEP: [[META6]] = !DISubroutineType(types: [[META7]])
+; MDEP: [[META7]] = !{}
+; MDEP: [[DBG8]] = !DILocation(line: 43, column: 1, scope: [[DBG5]])
+; MDEP: [[DBG9]] = !DILocation(line: 47, column: 1, scope: [[DBG5]])
+; MDEP: [[DBG10]] = !DILocation(line: 44, column: 1, scope: [[DBG5]])
+; MDEP: [[DBG11]] = !DILocation(line: 45, column: 1, scope: [[DBG5]])
+; MDEP: [[DBG12]] = !DILocation(line: 46, column: 1, scope: [[DBG5]])
+;.
+; MSSA: [[META3:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C99, file: [[META4:![0-9]+]], producer: "clang", isOptimized: true, flags: "-O2", runtimeVersion: 0, splitDebugFilename: "abc.debug", emissionKind: LineTablesOnly)
+; MSSA: [[META4]] = !DIFile(filename: "{{.*}}a.cc", directory: {{.*}})
+; MSSA: [[DBG5]] = distinct !DISubprogram(name: "foo", scope: [[META4]], file: [[META4]], line: 42, type: [[META6:![0-9]+]], scopeLine: 43, flags: DIFlagPrototyped, spFlags: DISPFlagDefinition, unit: [[META3]], retainedNodes: [[META7:![0-9]+]])
+; MSSA: [[META6]] = !DISubroutineType(types: [[META7]])
+; MSSA: [[META7]] = !{}
+; MSSA: [[DBG8]] = !DILocation(line: 43, column: 1, scope: [[DBG5]])
+; MSSA: [[DBG9]] = !DILocation(line: 45, column: 1, scope: [[DBG5]])
+; MSSA: [[DBG10]] = !DILocation(line: 44, column: 1, scope: [[DBG5]])
+; MSSA: [[DBG11]] = !DILocation(line: 46, column: 1, scope: [[DBG5]])
+; MSSA: [[DBG12]] = !DILocation(line: 47, column: 1, scope: [[DBG5]])
+;.
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll b/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll
index 9ca3e1b53f06c..60611a032ded5 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-aliasning-path.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -enable-load-pre -enable-pre -passes=gvn -S < %s | FileCheck %s
+; RUN: opt -enable-load-pre -enable-pre -passes=gvn -S < %s | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt -enable-load-pre -enable-pre -passes='gvn<memoryssa>' -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA
declare void @side_effect_0() nofree
@@ -102,25 +103,45 @@ exit:
}
define i32 @test_03(ptr %p) {
-; CHECK-LABEL: @test_03(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[X_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
-; CHECK-NEXT: br label [[LOOP:%.*]]
-; CHECK: loop:
-; CHECK-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
-; CHECK-NEXT: [[COND:%.*]] = icmp ult i32 [[X_PRE]], 100
-; CHECK-NEXT: br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]
-; CHECK: hot_path:
-; CHECK-NEXT: br label [[BACKEDGE]]
-; CHECK: cold_path:
-; CHECK-NEXT: call void @no_side_effect()
-; CHECK-NEXT: br label [[BACKEDGE]]
-; CHECK: backedge:
-; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X_PRE]]
-; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
-; CHECK-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
-; CHECK: exit:
-; CHECK-NEXT: ret i32 [[X_PRE]]
+; MDEP-LABEL: @test_03(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[X_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
+; MDEP-NEXT: br label [[LOOP:%.*]]
+; MDEP: loop:
+; MDEP-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; MDEP-NEXT: [[COND:%.*]] = icmp ult i32 [[X_PRE]], 100
+; MDEP-NEXT: br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]
+; MDEP: hot_path:
+; MDEP-NEXT: br label [[BACKEDGE]]
+; MDEP: cold_path:
+; MDEP-NEXT: call void @no_side_effect()
+; MDEP-NEXT: br label [[BACKEDGE]]
+; MDEP: backedge:
+; MDEP-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X_PRE]]
+; MDEP-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
+; MDEP-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
+; MDEP: exit:
+; MDEP-NEXT: ret i32 [[X_PRE]]
+;
+; MSSA-LABEL: @test_03(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: br label [[LOOP:%.*]]
+; MSSA: loop:
+; MSSA-NEXT: [[IV:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[BACKEDGE:%.*]] ]
+; MSSA-NEXT: [[X:%.*]] = load i32, ptr [[P:%.*]], align 4
+; MSSA-NEXT: [[COND:%.*]] = icmp ult i32 [[X]], 100
+; MSSA-NEXT: br i1 [[COND]], label [[HOT_PATH:%.*]], label [[COLD_PATH:%.*]]
+; MSSA: hot_path:
+; MSSA-NEXT: br label [[BACKEDGE]]
+; MSSA: cold_path:
+; MSSA-NEXT: call void @no_side_effect()
+; MSSA-NEXT: br label [[BACKEDGE]]
+; MSSA: backedge:
+; MSSA-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X]]
+; MSSA-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
+; MSSA-NEXT: br i1 [[LOOP_COND]], label [[LOOP]], label [[EXIT:%.*]]
+; MSSA: exit:
+; MSSA-NEXT: ret i32 [[X]]
;
entry:
br label %loop
diff --git a/llvm/test/Transforms/GVN/PRE/pre-basic-add.ll b/llvm/test/Transforms/GVN/PRE/pre-basic-add.ll
index f099ddcdbd7f5..9bf64962ecb1f 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-basic-add.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-basic-add.ll
@@ -1,33 +1,53 @@
-; RUN: opt < %s -passes=gvn -enable-pre -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn -enable-pre -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -enable-pre -S | FileCheck %s --check-prefixes=CHECK,MSSA
; RUN: opt < %s -passes="gvn<pre>" -enable-pre=false -S | FileCheck %s
@H = common global i32 0 ; <ptr> [#uses=2]
@G = common global i32 0 ; <ptr> [#uses=1]
define i32 @test() nounwind {
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: ) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr @H, align 4
+; CHECK-NEXT: [[TMP1:%.*]] = call i32 (...) @foo() #[[ATTR0]]
+; CHECK-NEXT: [[TMP2:%.*]] = icmp ne i32 [[TMP1]], 0
+; CHECK-NEXT: br i1 [[TMP2]], label %[[BB:.*]], label %[[ENTRY_BB1_CRIT_EDGE:.*]]
+; CHECK: [[ENTRY_BB1_CRIT_EDGE]]:
+; CHECK-NEXT: [[DOTPRE:%.*]] = add i32 [[TMP0]], 42
+; CHECK-NEXT: br label %[[BB1:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[TMP3:%.*]] = add i32 [[TMP0]], 42
+; CHECK-NEXT: store i32 [[TMP3]], ptr @G, align 4
+; CHECK-NEXT: br label %[[BB1]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[DOTPRE_PHI:%.*]] = phi i32 [ [[DOTPRE]], %[[ENTRY_BB1_CRIT_EDGE]] ], [ [[TMP3]], %[[BB]] ]
+; CHECK-NEXT: store i32 [[DOTPRE_PHI]], ptr @H, align 4
+; CHECK-NEXT: ret i32 0
+;
entry:
- %0 = load i32, ptr @H, align 4 ; <i32> [#uses=2]
- %1 = call i32 (...) @foo() nounwind ; <i32> [#uses=1]
- %2 = icmp ne i32 %1, 0 ; <i1> [#uses=1]
- br i1 %2, label %bb, label %bb1
+ %0 = load i32, ptr @H, align 4 ; <i32> [#uses=2]
+ %1 = call i32 (...) @foo() nounwind ; <i32> [#uses=1]
+ %2 = icmp ne i32 %1, 0 ; <i1> [#uses=1]
+ br i1 %2, label %bb, label %bb1
bb: ; preds = %entry
- %3 = add i32 %0, 42 ; <i32> [#uses=1]
-; CHECK: %.pre = add i32 %0, 42
- store i32 %3, ptr @G, align 4
- br label %bb1
+ %3 = add i32 %0, 42 ; <i32> [#uses=1]
+ store i32 %3, ptr @G, align 4
+ br label %bb1
bb1: ; preds = %bb, %entry
- %4 = add i32 %0, 42 ; <i32> [#uses=1]
- store i32 %4, ptr @H, align 4
- br label %return
+ %4 = add i32 %0, 42 ; <i32> [#uses=1]
+ store i32 %4, ptr @H, align 4
+ br label %return
-; CHECK: %.pre-phi = phi i32 [ %.pre, %entry.bb1_crit_edge ], [ %3, %bb ]
-; CHECK-NEXT: store i32 %.pre-phi, ptr @H, align 4
-; CHECK-NEXT: ret i32 0
return: ; preds = %bb1
- ret i32 0
+ ret i32 0
}
declare i32 @foo(...)
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
+; MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-jt-add.ll b/llvm/test/Transforms/GVN/PRE/pre-jt-add.ll
index 95f8f3ff31892..f62d06dbf0f84 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-jt-add.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-jt-add.ll
@@ -1,16 +1,33 @@
-; RUN: opt < %s -passes=gvn,jump-threading -enable-pre -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn,jump-threading -enable-pre -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>',jump-threading -enable-pre -S | FileCheck %s --check-prefixes=CHECK,MSSA
@H = common global i32 0
@G = common global i32 0
define i32 @test(i1 %cond, i32 %v) nounwind {
-; CHECK-LABEL: @test
+; CHECK-LABEL: define i32 @test(
+; CHECK-SAME: i1 [[COND:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br i1 [[COND]], label %[[BB:.*]], label %[[MERGE:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: store i32 -1, ptr @G, align 4
+; CHECK-NEXT: br label %[[MERGE]]
+; CHECK: [[MERGE]]:
+; CHECK-NEXT: [[ADD_2:%.*]] = add i32 [[V]], -1
+; CHECK-NEXT: [[CMP:%.*]] = icmp sgt i32 [[ADD_2]], 0
+; CHECK-NEXT: br i1 [[CMP]], label %[[ACTION:.*]], label %[[RETURN:.*]]
+; CHECK: [[ACTION]]:
+; CHECK-NEXT: store i32 [[ADD_2]], ptr @H, align 4
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[P:%.*]] = phi i32 [ 0, %[[MERGE]] ], [ 1, %[[ACTION]] ]
+; CHECK-NEXT: ret i32 [[P]]
+;
entry:
br i1 %cond, label %bb, label %bb1
bb:
-; CHECK: store
-; CHECK-NOT: br label %return
%add.1 = add nuw nsw i32 %v, -1
store i32 %add.1, ptr @G, align 4
br label %merge
@@ -24,8 +41,6 @@ merge:
br i1 %cmp, label %action, label %return
action:
-; CHECK: store
-; CHECK-NEXT: br label %return
store i32 %add.2, ptr @H, align 4
br label %return
@@ -34,3 +49,6 @@ return:
ret i32 %p
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
+; MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll b/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll
index 8c020fd036193..f961f23d6b10e 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-load-dbg.ll
@@ -1,4 +1,6 @@
-; RUN: opt < %s -passes=gvn -gvn-max-num-insns=22 -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn -gvn-max-num-insns=22 -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -gvn-max-num-insns=22 -S | FileCheck %s --check-prefixes=CHECK,MSSA
; Debug information should not impact gvn. The following two functions have same
; code except debug information. They should generate same optimized
@@ -11,13 +13,80 @@
@h = global %struct.a zeroinitializer, align 1
define void @withdbg() {
-; CHECK-LABEL: @withdbg
-; CHECK: [[PRE_PRE1:%.*]] = load i16, ptr @f, align 1
-; CHECK-NEXT: [[PRE_PRE2:%.*]] = load ptr, ptr @m, align 1
-; CHECK-NEXT: br i1 true, label %[[BLOCK1:.*]], label %[[BLOCK2:.*]]
-; CHECK: [[BLOCK1]]:
-; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[PRE_PRE1]] to i32
-; CHECK-NEXT: store i32 [[CONV]], ptr [[PRE_PRE2]], align 1
+; MDEP-LABEL: define void @withdbg() {
+; MDEP-NEXT: [[ENTRY:.*:]]
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1
+; MDEP-NEXT: [[TMP11_PRE:%.*]] = load i16, ptr @f, align 1
+; MDEP-NEXT: [[TMP12_PRE:%.*]] = load ptr, ptr @m, align 1
+; MDEP-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]]
+; MDEP: [[LOR_RHS]]:
+; MDEP-NEXT: #dbg_declare(ptr undef, [[META4:![0-9]+]], !DIExpression(), [[META14:![0-9]+]])
+; MDEP-NEXT: #dbg_declare(ptr undef, [[META10:![0-9]+]], !DIExpression(), [[META14]])
+; MDEP-NEXT: #dbg_declare(ptr undef, [[META11:![0-9]+]], !DIExpression(), [[META14]])
+; MDEP-NEXT: #dbg_declare(ptr undef, [[META12:![0-9]+]], !DIExpression(), [[META14]])
+; MDEP-NEXT: #dbg_declare(ptr undef, [[META13:![0-9]+]], !DIExpression(), [[META14]])
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: br label %[[LOR_END]]
+; MDEP: [[LOR_END]]:
+; MDEP-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11_PRE]] to i32
+; MDEP-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12_PRE]], align 1
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: define void @withdbg() {
+; MSSA-NEXT: [[ENTRY:.*:]]
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1
+; MSSA-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]]
+; MSSA: [[LOR_RHS]]:
+; MSSA-NEXT: #dbg_declare(ptr undef, [[META4:![0-9]+]], !DIExpression(), [[META14:![0-9]+]])
+; MSSA-NEXT: #dbg_declare(ptr undef, [[META10:![0-9]+]], !DIExpression(), [[META14]])
+; MSSA-NEXT: #dbg_declare(ptr undef, [[META11:![0-9]+]], !DIExpression(), [[META14]])
+; MSSA-NEXT: #dbg_declare(ptr undef, [[META12:![0-9]+]], !DIExpression(), [[META14]])
+; MSSA-NEXT: #dbg_declare(ptr undef, [[META13:![0-9]+]], !DIExpression(), [[META14]])
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[FVALUE:%.*]] = load i16, ptr @f, align 1
+; MSSA-NEXT: [[MVALUE:%.*]] = load ptr, ptr @m, align 1
+; MSSA-NEXT: br label %[[LOR_END]]
+; MSSA: [[LOR_END]]:
+; MSSA-NEXT: [[TMP11:%.*]] = load i16, ptr @f, align 1
+; MSSA-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11]] to i32
+; MSSA-NEXT: [[TMP12:%.*]] = load ptr, ptr @m, align 1
+; MSSA-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12]], align 1
+; MSSA-NEXT: ret void
+;
entry:
%agg.tmp.ensured.sroa.0.i = alloca i16, align 1
@@ -61,13 +130,70 @@ lor.end: ; preds = %lor.rhs, %entry
}
define void @lessdbg() {
-; CHECK-LABEL: @lessdbg
-; CHECK: [[PRE_PRE1:%.*]] = load i16, ptr @f, align 1
-; CHECK-NEXT: [[PRE_PRE2:%.*]] = load ptr, ptr @m, align 1
-; CHECK-NEXT: br i1 true, label %[[BLOCK1:.*]], label %[[BLOCK2:.*]]
-; CHECK: [[BLOCK1]]:
-; CHECK-NEXT: [[CONV:%.*]] = sext i16 [[PRE_PRE1]] to i32
-; CHECK-NEXT: store i32 [[CONV]], ptr [[PRE_PRE2]], align 1
+; MDEP-LABEL: define void @lessdbg() {
+; MDEP-NEXT: [[ENTRY:.*:]]
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1
+; MDEP-NEXT: [[TMP11_PRE:%.*]] = load i16, ptr @f, align 1
+; MDEP-NEXT: [[TMP12_PRE:%.*]] = load ptr, ptr @m, align 1
+; MDEP-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]]
+; MDEP: [[LOR_RHS]]:
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1
+; MDEP-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MDEP-NEXT: br label %[[LOR_END]]
+; MDEP: [[LOR_END]]:
+; MDEP-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11_PRE]] to i32
+; MDEP-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12_PRE]], align 1
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: define void @lessdbg() {
+; MSSA-NEXT: [[ENTRY:.*:]]
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_I:%.*]] = alloca i16, align 1
+; MSSA-NEXT: br i1 true, label %[[LOR_END:.*]], label %[[LOR_RHS:.*]]
+; MSSA: [[LOR_RHS]]:
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_1_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_2_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_3_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_4_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_5_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_6_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_7_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I:%.*]] = load volatile i16, ptr @h, align 1
+; MSSA-NEXT: store i16 [[AGG_TMP_ENSURED_SROA_0_0_COPYLOAD_8_I]], ptr [[AGG_TMP_ENSURED_SROA_0_I]], align 1
+; MSSA-NEXT: [[FVALUE:%.*]] = load i16, ptr @f, align 1
+; MSSA-NEXT: [[MVALUE:%.*]] = load ptr, ptr @m, align 1
+; MSSA-NEXT: br label %[[LOR_END]]
+; MSSA: [[LOR_END]]:
+; MSSA-NEXT: [[TMP11:%.*]] = load i16, ptr @f, align 1
+; MSSA-NEXT: [[CONV_I_I6:%.*]] = sext i16 [[TMP11]] to i32
+; MSSA-NEXT: [[TMP12:%.*]] = load ptr, ptr @m, align 1
+; MSSA-NEXT: store i32 [[CONV_I_I6]], ptr [[TMP12]], align 1
+; MSSA-NEXT: ret void
+;
entry:
%agg.tmp.ensured.sroa.0.i = alloca i16, align 1
@@ -126,3 +252,34 @@ declare void @llvm.dbg.declare(metadata, metadata, metadata)
!48 = !DILocalVariable(name: "v", scope: !41, file: !1, line: 15, type: !5)
!49 = !DILocalVariable(name: "d", scope: !41, file: !1, line: 15, type: !5)
!50 = !DILocalVariable(name: "u", scope: !41, file: !1, line: 16, type: !5)
+;.
+; MDEP: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+; MDEP: [[META1]] = !DIFile(filename: "{{.*}}bbi-78272.c", directory: {{.*}})
+; MDEP: [[META4]] = !DILocalVariable(name: "t", scope: [[META5:![0-9]+]], file: [[META1]], line: 15, type: [[META8:![0-9]+]])
+; MDEP: [[META5]] = distinct !DISubprogram(name: "x", scope: [[META1]], file: [[META1]], line: 14, type: [[META6:![0-9]+]], scopeLine: 14, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META9:![0-9]+]])
+; MDEP: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
+; MDEP: [[META7]] = !{[[META8]]}
+; MDEP: [[META8]] = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+; MDEP: [[META9]] = !{[[META4]], [[META10]], [[META11]], [[META12]], [[META13]]}
+; MDEP: [[META10]] = !DILocalVariable(name: "c", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]])
+; MDEP: [[META11]] = !DILocalVariable(name: "v", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]])
+; MDEP: [[META12]] = !DILocalVariable(name: "d", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]])
+; MDEP: [[META13]] = !DILocalVariable(name: "u", scope: [[META5]], file: [[META1]], line: 16, type: [[META8]])
+; MDEP: [[META14]] = !DILocation(line: 15, column: 7, scope: [[META5]])
+;.
+; MSSA: [[META0:![0-9]+]] = distinct !DICompileUnit(language: DW_LANG_C11, file: [[META1:![0-9]+]], producer: "{{.*}}clang version {{.*}}", isOptimized: true, runtimeVersion: 0, emissionKind: FullDebug, splitDebugInlining: false, nameTableKind: None)
+; MSSA: [[META1]] = !DIFile(filename: "{{.*}}bbi-78272.c", directory: {{.*}})
+; MSSA: [[META4]] = !DILocalVariable(name: "t", scope: [[META5:![0-9]+]], file: [[META1]], line: 15, type: [[META8:![0-9]+]])
+; MSSA: [[META5]] = distinct !DISubprogram(name: "x", scope: [[META1]], file: [[META1]], line: 14, type: [[META6:![0-9]+]], scopeLine: 14, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagLocalToUnit | DISPFlagDefinition | DISPFlagOptimized, unit: [[META0]], retainedNodes: [[META9:![0-9]+]])
+; MSSA: [[META6]] = !DISubroutineType(types: [[META7:![0-9]+]])
+; MSSA: [[META7]] = !{[[META8]]}
+; MSSA: [[META8]] = !DIBasicType(name: "int", size: 16, encoding: DW_ATE_signed)
+; MSSA: [[META9]] = !{[[META4]], [[META10]], [[META11]], [[META12]], [[META13]]}
+; MSSA: [[META10]] = !DILocalVariable(name: "c", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]])
+; MSSA: [[META11]] = !DILocalVariable(name: "v", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]])
+; MSSA: [[META12]] = !DILocalVariable(name: "d", scope: [[META5]], file: [[META1]], line: 15, type: [[META8]])
+; MSSA: [[META13]] = !DILocalVariable(name: "u", scope: [[META5]], file: [[META1]], line: 16, type: [[META8]])
+; MSSA: [[META14]] = !DILocation(line: 15, column: 7, scope: [[META5]])
+;.
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll b/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll
index 1ca907df35215..ca1852f49bf31 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-load-guards.ll
@@ -1,4 +1,6 @@
-; RUN: opt < %s -passes=gvn -enable-load-pre -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn -enable-load-pre -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -enable-load-pre -S | FileCheck %s --check-prefixes=CHECK,MSSA
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"
declare void @llvm.experimental.guard(i1, ...)
@@ -8,20 +10,33 @@ declare void @llvm.experimental.guard(i1, ...)
; the element in this case and deoptimize otherwise. If we hoist the load to a
; place above the guard, it will may lead to out-of-bound array access.
define i32 @test_motivation(ptr %p, ptr %q, i1 %C, i32 %index, i32 %len) {
-; CHECK-LABEL: @test_motivation(
+; CHECK-LABEL: define i32 @test_motivation(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i32 [[INDEX:%.*]], i32 [[LEN:%.*]]) {
+; CHECK-NEXT: [[BLOCK1:.*:]]
+; CHECK-NEXT: [[EL1:%.*]] = getelementptr inbounds i32, ptr [[Q]], i32 [[INDEX]]
+; CHECK-NEXT: [[EL2:%.*]] = getelementptr inbounds i32, ptr [[P]], i32 [[INDEX]]
+; CHECK-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]]
+; CHECK: [[BLOCK2]]:
+; CHECK-NEXT: br label %[[BLOCK4:.*]]
+; CHECK: [[BLOCK3]]:
+; CHECK-NEXT: store i32 0, ptr [[EL1]], align 4
+; CHECK-NEXT: br label %[[BLOCK4]]
+; CHECK: [[BLOCK4]]:
+; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[EL2]], %[[BLOCK3]] ], [ [[EL1]], %[[BLOCK2]] ]
+; CHECK-NEXT: [[COND1:%.*]] = icmp sge i32 [[INDEX]], 0
+; CHECK-NEXT: [[COND2:%.*]] = icmp slt i32 [[INDEX]], [[LEN]]
+; CHECK-NEXT: [[IN_BOUNDS:%.*]] = and i1 [[COND1]], [[COND2]]
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[IN_BOUNDS]]) [ "deopt"() ]
+; CHECK-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4
+; CHECK-NEXT: ret i32 [[PRE]]
+;
block1:
%el1 = getelementptr inbounds i32, ptr %q, i32 %index
%el2 = getelementptr inbounds i32, ptr %p, i32 %index
- br i1 %C, label %block2, label %block3
+ br i1 %C, label %block2, label %block3
block2:
-; CHECK: block2:
-; CHECK-NEXT: br
-; CHECK-NOT: load
-; CHECK-NOT: sge
-; CHECK-NOT: slt
-; CHECK-NOT: and
br label %block4
block3:
@@ -30,13 +45,6 @@ block3:
block4:
-; CHECK: block4:
-; CHECK: %cond1 = icmp sge i32 %index, 0
-; CHECK-NEXT: %cond2 = icmp slt i32 %index, %len
-; CHECK-NEXT: %in.bounds = and i1 %cond1, %cond2
-; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %in.bounds)
-; CHECK-NEXT: %PRE = load i32, ptr %P2
-; CHECK: ret i32 %PRE
%P2 = phi ptr [%el2, %block3], [%el1, %block2]
%cond1 = icmp sge i32 %index, 0
@@ -49,17 +57,28 @@ block4:
; Guard in load's block that is above the load should prohibit the PRE.
define i32 @test_guard_01(ptr %p, ptr %q, i1 %C, i1 %G) {
-; CHECK-LABEL: @test_guard_01(
+; CHECK-LABEL: define i32 @test_guard_01(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) {
+; CHECK-NEXT: [[BLOCK1:.*:]]
+; CHECK-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]]
+; CHECK: [[BLOCK2]]:
+; CHECK-NEXT: br label %[[BLOCK4:.*]]
+; CHECK: [[BLOCK3]]:
+; CHECK-NEXT: store i32 0, ptr [[P]], align 4
+; CHECK-NEXT: br label %[[BLOCK4]]
+; CHECK: [[BLOCK4]]:
+; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ]
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ]
+; CHECK-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4
+; CHECK-NEXT: ret i32 [[PRE]]
+;
block1:
- br i1 %C, label %block2, label %block3
+ br i1 %C, label %block2, label %block3
block2:
-; CHECK: block2:
-; CHECK-NEXT: br
-; CHECK-NOT: load
- br label %block4
+ br label %block4
block3:
store i32 0, ptr %p
@@ -67,10 +86,6 @@ block3:
block4:
-; CHECK: block4:
-; CHECK: call void (i1, ...) @llvm.experimental.guard(i1 %G)
-; CHECK-NEXT: load
-; CHECK: ret i32
%P2 = phi ptr [%p, %block3], [%q, %block2]
call void (i1, ...) @llvm.experimental.guard(i1 %G) [ "deopt"() ]
@@ -80,16 +95,44 @@ block4:
; Guard in load's block that is below the load should not prohibit the PRE.
define i32 @test_guard_02(ptr %p, ptr %q, i1 %C, i1 %G) {
-; CHECK-LABEL: @test_guard_02(
+; MDEP-LABEL: define i32 @test_guard_02(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) {
+; MDEP-NEXT: [[BLOCK1:.*:]]
+; MDEP-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]]
+; MDEP: [[BLOCK2]]:
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q]], align 4
+; MDEP-NEXT: br label %[[BLOCK4:.*]]
+; MDEP: [[BLOCK3]]:
+; MDEP-NEXT: store i32 0, ptr [[P]], align 4
+; MDEP-NEXT: br label %[[BLOCK4]]
+; MDEP: [[BLOCK4]]:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, %[[BLOCK3]] ], [ [[PRE_PRE]], %[[BLOCK2]] ]
+; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ]
+; MDEP-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ]
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: define i32 @test_guard_02(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) {
+; MSSA-NEXT: [[BLOCK1:.*:]]
+; MSSA-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]]
+; MSSA: [[BLOCK2]]:
+; MSSA-NEXT: br label %[[BLOCK4:.*]]
+; MSSA: [[BLOCK3]]:
+; MSSA-NEXT: store i32 0, ptr [[P]], align 4
+; MSSA-NEXT: br label %[[BLOCK4]]
+; MSSA: [[BLOCK4]]:
+; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ]
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4
+; MSSA-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ]
+; MSSA-NEXT: ret i32 [[PRE]]
+;
block1:
- br i1 %C, label %block2, label %block3
+ br i1 %C, label %block2, label %block3
block2:
-; CHECK: block2:
-; CHECK-NEXT: load i32, ptr %q
- br label %block4
+ br label %block4
block3:
store i32 0, ptr %p
@@ -97,12 +140,6 @@ block3:
block4:
-; CHECK: block4:
-; CHECK-NEXT: phi i32 [
-; CHECK-NEXT: phi ptr [
-; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %G)
-; CHECK-NOT: load
-; CHECK: ret i32
%P2 = phi ptr [%p, %block3], [%q, %block2]
%PRE = load i32, ptr %P2
@@ -112,17 +149,28 @@ block4:
; Guard above the load's block should prevent PRE from hoisting through it.
define i32 @test_guard_03(ptr %p, ptr %q, i1 %C, i1 %G) {
-; CHECK-LABEL: @test_guard_03(
+; CHECK-LABEL: define i32 @test_guard_03(
+; CHECK-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[C:%.*]], i1 [[G:%.*]]) {
+; CHECK-NEXT: [[BLOCK1:.*:]]
+; CHECK-NEXT: br i1 [[C]], label %[[BLOCK2:.*]], label %[[BLOCK3:.*]]
+; CHECK: [[BLOCK2]]:
+; CHECK-NEXT: br label %[[BLOCK4:.*]]
+; CHECK: [[BLOCK3]]:
+; CHECK-NEXT: store i32 0, ptr [[P]], align 4
+; CHECK-NEXT: br label %[[BLOCK4]]
+; CHECK: [[BLOCK4]]:
+; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], %[[BLOCK3]] ], [ [[Q]], %[[BLOCK2]] ]
+; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 [[G]]) [ "deopt"() ]
+; CHECK-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4
+; CHECK-NEXT: ret i32 [[PRE]]
+;
block1:
- br i1 %C, label %block2, label %block3
+ br i1 %C, label %block2, label %block3
block2:
-; CHECK: block2:
-; CHECK-NEXT: br
-; CHECK-NOT: load
- br label %block4
+ br label %block4
block3:
store i32 0, ptr %p
@@ -130,11 +178,6 @@ block3:
block4:
-; CHECK: block4:
-; CHECK-NEXT: phi ptr
-; CHECK-NEXT: call void (i1, ...) @llvm.experimental.guard(i1 %G)
-; CHECK-NEXT: load
-; CHECK-NEXT: ret i32
%P2 = phi ptr [%p, %block3], [%q, %block2]
call void (i1, ...) @llvm.experimental.guard(i1 %G) [ "deopt"() ]
diff --git a/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll b/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll
index 0585781e7985f..17fbc0e38ec66 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-load-implicit-cf-updates.ll
@@ -1,4 +1,6 @@
-; RUN: opt -S -passes=gvn -enable-load-pre < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=gvn -enable-load-pre < %s | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt -S -passes='gvn<memoryssa>' -enable-load-pre < %s | FileCheck %s --check-prefixes=CHECK,MSSA
target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
@@ -9,18 +11,28 @@ target datalayout = "e-m:e-i64:64-f80:128-n8:16:32:64-S128"
declare i32 @foo(i32 %arg) #0
define hidden void @test_01(i32 %x, i32 %y) {
-
; c2 only throws if c1 throws, so it can be safely removed and then PRE can
; hoist the load out of loop.
-
-; CHECK-LABEL: @test_01
-; CHECK: entry:
-; CHECK-NEXT: %c1 = call i32 @foo(i32 %x)
-; CHECK-NEXT: %val.pre = load i32, ptr null, align 8
-; CHECK-NEXT: br label %loop
-; CHECK: loop:
-; CHECK-NEXT: %c3 = call i32 @foo(i32 %val.pre)
-; CHECK-NEXT: br label %loop
+; MDEP-LABEL: define hidden void @test_01(
+; MDEP-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; MDEP-NEXT: [[ENTRY:.*:]]
+; MDEP-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]])
+; MDEP-NEXT: [[VAL_PRE:%.*]] = load i32, ptr null, align 8
+; MDEP-NEXT: br label %[[LOOP:.*]]
+; MDEP: [[LOOP]]:
+; MDEP-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[VAL_PRE]])
+; MDEP-NEXT: br label %[[LOOP]]
+;
+; MSSA-LABEL: define hidden void @test_01(
+; MSSA-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; MSSA-NEXT: [[ENTRY:.*:]]
+; MSSA-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]])
+; MSSA-NEXT: br label %[[LOOP:.*]]
+; MSSA: [[LOOP]]:
+; MSSA-NEXT: [[VAL:%.*]] = load i32, ptr null, align 8
+; MSSA-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[VAL]])
+; MSSA-NEXT: br label %[[LOOP]]
+;
entry:
%c1 = call i32 @foo(i32 %x)
@@ -34,18 +46,18 @@ loop:
}
define hidden void @test_02(i32 %x, i32 %y) {
-
; PRE is not allowed because c2 may throw.
-
-; CHECK-LABEL: @test_02
-; CHECK: entry:
-; CHECK-NEXT: %c1 = call i32 @foo(i32 %x)
-; CHECK-NEXT: br label %loop
-; CHECK: loop:
-; CHECK-NEXT: %c2 = call i32 @foo(i32 %y)
-; CHECK-NEXT: %val = load i32, ptr null, align 8
-; CHECK-NEXT: %c3 = call i32 @foo(i32 %val)
-; CHECK-NEXT: br label %loop
+; CHECK-LABEL: define hidden void @test_02(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]])
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[C2:%.*]] = call i32 @foo(i32 [[Y]])
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr null, align 8
+; CHECK-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[VAL]])
+; CHECK-NEXT: br label %[[LOOP]]
+;
entry:
%c1 = call i32 @foo(i32 %x)
@@ -59,19 +71,31 @@ loop:
}
define hidden void @test_03(i32 %x, i32 %y) {
-
; PRE of load is allowed because c2 only throws if c1 throws. c3 should
; not be eliminated. c4 is eliminated because it only throws if c3 throws.
-
-; CHECK-LABEL: @test_03
-; CHECK: entry:
-; CHECK-NEXT: %c1 = call i32 @foo(i32 %x)
-; CHECK-NEXT: %val.pre = load i32, ptr null, align 8
-; CHECK-NEXT: br label %loop
-; CHECK: loop:
-; CHECK-NEXT: %c3 = call i32 @foo(i32 %y)
-; CHECK-NEXT: %c5 = call i32 @foo(i32 %val.pre)
-; CHECK-NEXT: br label %loop
+; MDEP-LABEL: define hidden void @test_03(
+; MDEP-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; MDEP-NEXT: [[ENTRY:.*:]]
+; MDEP-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]])
+; MDEP-NEXT: [[VAL_PRE:%.*]] = load i32, ptr null, align 8
+; MDEP-NEXT: br label %[[LOOP:.*]]
+; MDEP: [[LOOP]]:
+; MDEP-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[Y]])
+; MDEP-NEXT: [[C5:%.*]] = call i32 @foo(i32 [[VAL_PRE]])
+; MDEP-NEXT: br label %[[LOOP]]
+;
+; MSSA-LABEL: define hidden void @test_03(
+; MSSA-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; MSSA-NEXT: [[ENTRY:.*:]]
+; MSSA-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]])
+; MSSA-NEXT: br label %[[LOOP:.*]]
+; MSSA: [[LOOP]]:
+; MSSA-NEXT: [[VAL:%.*]] = load i32, ptr null, align 8
+; MSSA-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[Y]])
+; MSSA-NEXT: [[VAL2:%.*]] = load i32, ptr null, align 8
+; MSSA-NEXT: [[C5:%.*]] = call i32 @foo(i32 [[VAL]])
+; MSSA-NEXT: br label %[[LOOP]]
+;
entry:
%c1 = call i32 @foo(i32 %x)
@@ -88,18 +112,18 @@ loop:
}
define hidden void @test_04(i32 %x, i32 %y) {
-
; PRE is not allowed even after we remove c2 because now c3 prevents us from it.
-
-; CHECK-LABEL: @test_04
-; CHECK: entry:
-; CHECK-NEXT: %c1 = call i32 @foo(i32 %x)
-; CHECK-NEXT: br label %loop
-; CHECK: loop:
-; CHECK-NEXT: %c3 = call i32 @foo(i32 %y)
-; CHECK-NEXT: %val = load i32, ptr null, align 8
-; CHECK-NEXT: %c5 = call i32 @foo(i32 %val)
-; CHECK-NEXT: br label %loop
+; CHECK-LABEL: define hidden void @test_04(
+; CHECK-SAME: i32 [[X:%.*]], i32 [[Y:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[C1:%.*]] = call i32 @foo(i32 [[X]])
+; CHECK-NEXT: br label %[[LOOP:.*]]
+; CHECK: [[LOOP]]:
+; CHECK-NEXT: [[C3:%.*]] = call i32 @foo(i32 [[Y]])
+; CHECK-NEXT: [[VAL:%.*]] = load i32, ptr null, align 8
+; CHECK-NEXT: [[C5:%.*]] = call i32 @foo(i32 [[VAL]])
+; CHECK-NEXT: br label %[[LOOP]]
+;
entry:
%c1 = call i32 @foo(i32 %x)
diff --git a/llvm/test/Transforms/GVN/PRE/pre-load.ll b/llvm/test/Transforms/GVN/PRE/pre-load.ll
index bbd20bccdc166..5a07f9f7aa6de 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-load.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-load.ll
@@ -1,21 +1,34 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt < %s -passes=gvn -enable-load-pre -S | FileCheck %s
+; RUN: opt < %s -passes=gvn -enable-load-pre -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -enable-load-pre -S | FileCheck %s --check-prefixes=CHECK,MSSA
; RUN: opt < %s -aa-pipeline=basic-aa -passes="gvn<load-pre>" -enable-load-pre=false -S | FileCheck %s
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
define i32 @test1(ptr %p, i1 %C) {
-; CHECK-LABEL: @test1(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: store i32 0, ptr [[P]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
-; CHECK-NEXT: ret i32 [[PRE]]
+; MDEP-LABEL: @test1(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: store i32 0, ptr [[P]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: @test1(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: br label [[BLOCK4:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P]], align 4
+; MSSA-NEXT: ret i32 [[PRE]]
;
block1:
br i1 %C, label %block2, label %block3
@@ -34,19 +47,32 @@ block4:
; This is a simple phi translation case.
define i32 @test2(ptr %p, ptr %q, i1 %C) {
-; CHECK-LABEL: @test2(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q:%.*]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: store i32 0, ptr [[P:%.*]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
-; CHECK-NEXT: ret i32 [[PRE]]
+; MDEP-LABEL: @test2(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[Q:%.*]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: @test2(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: br label [[BLOCK4:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q:%.*]], [[BLOCK2]] ]
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P2]], align 4
+; MSSA-NEXT: ret i32 [[PRE]]
;
block1:
br i1 %C, label %block2, label %block3
@@ -66,23 +92,40 @@ block4:
; This is a PRE case that requires phi translation through a GEP.
define i32 @test3(ptr %p, ptr %q, ptr %Hack, i1 %C) {
-; CHECK-LABEL: @test3(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
-; CHECK-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[B]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
-; CHECK-NEXT: store i32 0, ptr [[A]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
-; CHECK-NEXT: ret i32 [[PRE]]
+; MDEP-LABEL: @test3(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
+; MDEP-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[B]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MDEP-NEXT: store i32 0, ptr [[A]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: @test3(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
+; MSSA-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: br label [[BLOCK4:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MSSA-NEXT: store i32 0, ptr [[A]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MSSA-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4
+; MSSA-NEXT: ret i32 [[PRE]]
;
block1:
%B = getelementptr i32, ptr %q, i32 1
@@ -107,24 +150,41 @@ block4:
;; Here the loaded address is available, but the computation is in 'block3'
;; which does not dominate 'block2'.
define i32 @test4(ptr %p, ptr %q, ptr %Hack, i1 %C) {
-; CHECK-LABEL: @test4(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1
-; CHECK-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
-; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
-; CHECK-NEXT: store i32 0, ptr [[A]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
-; CHECK-NEXT: ret i32 [[PRE]]
+; MDEP-LABEL: @test4(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1
+; MDEP-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
+; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MDEP-NEXT: store i32 0, ptr [[A]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: @test4(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: br label [[BLOCK4:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
+; MSSA-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
+; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MSSA-NEXT: store i32 0, ptr [[A]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MSSA-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4
+; MSSA-NEXT: ret i32 [[PRE]]
;
block1:
br i1 %C, label %block2, label %block3
@@ -149,24 +209,41 @@ block4:
; Same as test4, with a nuw flag on the GEP.
define i32 @test4_nuw(ptr %p, ptr %q, ptr %Hack, i1 %C) {
-; CHECK-LABEL: @test4_nuw(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr nuw i32, ptr [[Q:%.*]], i32 1
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1
-; CHECK-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
-; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
-; CHECK-NEXT: store i32 0, ptr [[A]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P3:%.*]] = getelementptr nuw i32, ptr [[P2]], i32 1
-; CHECK-NEXT: ret i32 [[PRE]]
+; MDEP-LABEL: @test4_nuw(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr nuw i32, ptr [[Q:%.*]], i32 1
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q]], i32 1
+; MDEP-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
+; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MDEP-NEXT: store i32 0, ptr [[A]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P3:%.*]] = getelementptr nuw i32, ptr [[P2]], i32 1
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: @test4_nuw(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: br label [[BLOCK4:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: [[B:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
+; MSSA-NEXT: store ptr [[B]], ptr [[HACK:%.*]], align 8
+; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MSSA-NEXT: store i32 0, ptr [[A]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MSSA-NEXT: [[P3:%.*]] = getelementptr nuw i32, ptr [[P2]], i32 1
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4
+; MSSA-NEXT: ret i32 [[PRE]]
;
block1:
br i1 %C, label %block2, label %block3
@@ -196,28 +273,50 @@ block4:
;}
define void @test5(i32 %N, ptr nocapture %G) nounwind ssp {
-; CHECK-LABEL: @test5(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0
-; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
-; CHECK: bb.nph:
-; CHECK-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64
-; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8
-; CHECK-NEXT: br label [[BB:%.*]]
-; CHECK: bb:
-; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP3:%.*]], [[BB]] ]
-; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
-; CHECK-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1
-; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]]
-; CHECK-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
-; CHECK-NEXT: [[TMP3]] = load double, ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]]
-; CHECK-NEXT: store double [[TMP4]], ptr [[SCEVGEP7]], align 8
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
-; CHECK: return:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test5(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0
+; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MDEP: bb.nph:
+; MDEP-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64
+; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8
+; MDEP-NEXT: br label [[BB:%.*]]
+; MDEP: bb:
+; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP3:%.*]], [[BB]] ]
+; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
+; MDEP-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1
+; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]]
+; MDEP-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
+; MDEP-NEXT: [[TMP3]] = load double, ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]]
+; MDEP-NEXT: store double [[TMP4]], ptr [[SCEVGEP7]], align 8
+; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]]
+; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MDEP: return:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test5(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0
+; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MSSA: bb.nph:
+; MSSA-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64
+; MSSA-NEXT: br label [[BB:%.*]]
+; MSSA: bb:
+; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
+; MSSA-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1
+; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[TMP6]]
+; MSSA-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
+; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP7]], align 8
+; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]]
+; MSSA-NEXT: store double [[TMP4]], ptr [[SCEVGEP7]], align 8
+; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]]
+; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MSSA: return:
+; MSSA-NEXT: ret void
;
entry:
%0 = add i32 %N, -1
@@ -254,28 +353,50 @@ return:
;}
define void @test6(i32 %N, ptr nocapture %G) nounwind ssp {
-; CHECK-LABEL: @test6(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0
-; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
-; CHECK: bb.nph:
-; CHECK-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64
-; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8
-; CHECK-NEXT: br label [[BB:%.*]]
-; CHECK: bb:
-; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ]
-; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
-; CHECK-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1
-; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]]
-; CHECK-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
-; CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]]
-; CHECK-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
-; CHECK: return:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test6(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0
+; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MDEP: bb.nph:
+; MDEP-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64
+; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[G:%.*]], align 8
+; MDEP-NEXT: br label [[BB:%.*]]
+; MDEP: bb:
+; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ]
+; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
+; MDEP-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1
+; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP6]]
+; MDEP-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
+; MDEP-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]]
+; MDEP-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]]
+; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MDEP: return:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test6(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 0
+; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MSSA: bb.nph:
+; MSSA-NEXT: [[TMP:%.*]] = zext i32 [[TMP0]] to i64
+; MSSA-NEXT: br label [[BB:%.*]]
+; MSSA: bb:
+; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
+; MSSA-NEXT: [[TMP6]] = add i64 [[INDVAR]], 1
+; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[TMP6]]
+; MSSA-NEXT: [[SCEVGEP7:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
+; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP7]], align 8
+; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]]
+; MSSA-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP6]], [[TMP]]
+; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MSSA: return:
+; MSSA-NEXT: ret void
;
entry:
%0 = add i32 %N, -1
@@ -314,31 +435,57 @@ return:
; This requires phi translation of the adds.
define void @test7(i32 %N, ptr nocapture %G) nounwind ssp {
-; CHECK-LABEL: @test7(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[G:%.*]], i64 1
-; CHECK-NEXT: store double 1.000000e+00, ptr [[TMP0]], align 8
-; CHECK-NEXT: [[TMP1:%.*]] = add i32 [[N:%.*]], -1
-; CHECK-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 1
-; CHECK-NEXT: br i1 [[TMP2]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
-; CHECK: bb.nph:
-; CHECK-NEXT: [[TMP:%.*]] = sext i32 [[TMP1]] to i64
-; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1
-; CHECK-NEXT: br label [[BB:%.*]]
-; CHECK: bb:
-; CHECK-NEXT: [[TMP3:%.*]] = phi double [ 1.000000e+00, [[BB_NPH]] ], [ [[TMP5:%.*]], [[BB]] ]
-; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2
-; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]]
-; CHECK-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1
-; CHECK-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
-; CHECK-NEXT: [[TMP4:%.*]] = load double, ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[TMP5]] = fadd double [[TMP3]], [[TMP4]]
-; CHECK-NEXT: store double [[TMP5]], ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
-; CHECK: return:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test7(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[G:%.*]], i64 1
+; MDEP-NEXT: store double 1.000000e+00, ptr [[TMP0]], align 8
+; MDEP-NEXT: [[TMP1:%.*]] = add i32 [[N:%.*]], -1
+; MDEP-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 1
+; MDEP-NEXT: br i1 [[TMP2]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MDEP: bb.nph:
+; MDEP-NEXT: [[TMP:%.*]] = sext i32 [[TMP1]] to i64
+; MDEP-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1
+; MDEP-NEXT: br label [[BB:%.*]]
+; MDEP: bb:
+; MDEP-NEXT: [[TMP3:%.*]] = phi double [ 1.000000e+00, [[BB_NPH]] ], [ [[TMP5:%.*]], [[BB]] ]
+; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ]
+; MDEP-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2
+; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]]
+; MDEP-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1
+; MDEP-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
+; MDEP-NEXT: [[TMP4:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[TMP5]] = fadd double [[TMP3]], [[TMP4]]
+; MDEP-NEXT: store double [[TMP5]], ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]]
+; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MDEP: return:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test7(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TMP0:%.*]] = getelementptr inbounds double, ptr [[G:%.*]], i64 1
+; MSSA-NEXT: store double 1.000000e+00, ptr [[TMP0]], align 8
+; MSSA-NEXT: [[TMP1:%.*]] = add i32 [[N:%.*]], -1
+; MSSA-NEXT: [[TMP2:%.*]] = icmp sgt i32 [[TMP1]], 1
+; MSSA-NEXT: br i1 [[TMP2]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MSSA: bb.nph:
+; MSSA-NEXT: [[TMP:%.*]] = sext i32 [[TMP1]] to i64
+; MSSA-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1
+; MSSA-NEXT: br label [[BB:%.*]]
+; MSSA: bb:
+; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ]
+; MSSA-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2
+; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]]
+; MSSA-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1
+; MSSA-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
+; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP10]], align 8
+; MSSA-NEXT: [[TMP4:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]]
+; MSSA-NEXT: store double [[TMP5]], ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]]
+; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MSSA: return:
+; MSSA-NEXT: ret void
;
entry:
%0 = getelementptr inbounds double, ptr %G, i64 1
@@ -374,22 +521,37 @@ return:
;; Here the loaded address isn't available in 'block2' at all, requiring a new
;; GEP to be inserted into it.
define i32 @test8(ptr %p, ptr %q, ptr %Hack, i1 %C) {
-; CHECK-LABEL: @test8(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
-; CHECK-NEXT: store i32 0, ptr [[A]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
-; CHECK-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
-; CHECK-NEXT: ret i32 [[PRE]]
+; MDEP-LABEL: @test8(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[P3_PHI_TRANS_INSERT:%.*]] = getelementptr i32, ptr [[Q:%.*]], i32 1
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P3_PHI_TRANS_INSERT]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MDEP-NEXT: store i32 0, ptr [[A]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ 0, [[BLOCK3]] ], [ [[PRE_PRE]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q]], [[BLOCK2]] ]
+; MDEP-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
+; MDEP-NEXT: ret i32 [[PRE]]
+;
+; MSSA-LABEL: @test8(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: br label [[BLOCK4:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: [[A:%.*]] = getelementptr i32, ptr [[P:%.*]], i32 1
+; MSSA-NEXT: store i32 0, ptr [[A]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[P2:%.*]] = phi ptr [ [[P]], [[BLOCK3]] ], [ [[Q:%.*]], [[BLOCK2]] ]
+; MSSA-NEXT: [[P3:%.*]] = getelementptr i32, ptr [[P2]], i32 1
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P3]], align 4
+; MSSA-NEXT: ret i32 [[PRE]]
;
block1:
br i1 %C, label %block2, label %block3
@@ -417,31 +579,55 @@ block4:
; This requires phi translation of the adds.
define void @test9(i32 %N, ptr nocapture %G) nounwind ssp {
-; CHECK-LABEL: @test9(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1
-; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
-; CHECK: bb.nph:
-; CHECK-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64
-; CHECK-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1
-; CHECK-NEXT: [[SCEVGEP10_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1
-; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP10_PHI_TRANS_INSERT]], align 8
-; CHECK-NEXT: br label [[BB:%.*]]
-; CHECK: bb:
-; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ]
-; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ]
-; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2
-; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]]
-; CHECK-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1
-; CHECK-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
-; CHECK-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]]
-; CHECK-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
-; CHECK: return:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test9(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1
+; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MDEP: bb.nph:
+; MDEP-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64
+; MDEP-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1
+; MDEP-NEXT: [[SCEVGEP10_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1
+; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP10_PHI_TRANS_INSERT]], align 8
+; MDEP-NEXT: br label [[BB:%.*]]
+; MDEP: bb:
+; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ]
+; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ]
+; MDEP-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2
+; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP8]]
+; MDEP-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1
+; MDEP-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
+; MDEP-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[TMP4]] = fadd double [[TMP2]], [[TMP3]]
+; MDEP-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8
+; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]]
+; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MDEP: return:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test9(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1
+; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MSSA: bb.nph:
+; MSSA-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64
+; MSSA-NEXT: [[TMP7:%.*]] = add i64 [[TMP]], -1
+; MSSA-NEXT: br label [[BB:%.*]]
+; MSSA: bb:
+; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP9:%.*]], [[BB]] ]
+; MSSA-NEXT: [[TMP8:%.*]] = add i64 [[INDVAR]], 2
+; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[TMP8]]
+; MSSA-NEXT: [[TMP9]] = add i64 [[INDVAR]], 1
+; MSSA-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
+; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP10]], align 8
+; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]]
+; MSSA-NEXT: store double [[TMP4]], ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP9]], [[TMP7]]
+; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MSSA: return:
+; MSSA-NEXT: ret void
;
entry:
add i32 0, 0
@@ -482,35 +668,62 @@ return:
; PR5501
define void @test10(i32 %N, ptr nocapture %G) nounwind ssp {
-; CHECK-LABEL: @test10(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
-; CHECK-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1
-; CHECK-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
-; CHECK: bb.nph:
-; CHECK-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64
-; CHECK-NEXT: [[TMP8:%.*]] = add i64 [[TMP]], -1
-; CHECK-NEXT: [[SCEVGEP12_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1
-; CHECK-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP12_PHI_TRANS_INSERT]], align 8
-; CHECK-NEXT: [[DOTPRE1:%.*]] = load double, ptr [[G]], align 8
-; CHECK-NEXT: br label [[BB:%.*]]
-; CHECK: bb:
-; CHECK-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE1]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
-; CHECK-NEXT: [[TMP3:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ]
-; CHECK-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP11:%.*]], [[BB]] ]
-; CHECK-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
-; CHECK-NEXT: [[TMP9:%.*]] = add i64 [[INDVAR]], 2
-; CHECK-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
-; CHECK-NEXT: [[TMP11]] = add i64 [[INDVAR]], 1
-; CHECK-NEXT: [[SCEVGEP12:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP11]]
-; CHECK-NEXT: [[TMP4]] = load double, ptr [[SCEVGEP10]], align 8
-; CHECK-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]]
-; CHECK-NEXT: [[TMP6]] = fadd double [[TMP5]], [[TMP2]]
-; CHECK-NEXT: store double [[TMP6]], ptr [[SCEVGEP12]], align 8
-; CHECK-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP11]], [[TMP8]]
-; CHECK-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
-; CHECK: return:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test10(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MDEP-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1
+; MDEP-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MDEP: bb.nph:
+; MDEP-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64
+; MDEP-NEXT: [[TMP8:%.*]] = add i64 [[TMP]], -1
+; MDEP-NEXT: [[SCEVGEP12_PHI_TRANS_INSERT:%.*]] = getelementptr double, ptr [[G:%.*]], i64 1
+; MDEP-NEXT: [[DOTPRE:%.*]] = load double, ptr [[SCEVGEP12_PHI_TRANS_INSERT]], align 8
+; MDEP-NEXT: [[DOTPRE1:%.*]] = load double, ptr [[G]], align 8
+; MDEP-NEXT: br label [[BB:%.*]]
+; MDEP: bb:
+; MDEP-NEXT: [[TMP2:%.*]] = phi double [ [[DOTPRE1]], [[BB_NPH]] ], [ [[TMP6:%.*]], [[BB]] ]
+; MDEP-NEXT: [[TMP3:%.*]] = phi double [ [[DOTPRE]], [[BB_NPH]] ], [ [[TMP4:%.*]], [[BB]] ]
+; MDEP-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP11:%.*]], [[BB]] ]
+; MDEP-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G]], i64 [[INDVAR]]
+; MDEP-NEXT: [[TMP9:%.*]] = add i64 [[INDVAR]], 2
+; MDEP-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
+; MDEP-NEXT: [[TMP11]] = add i64 [[INDVAR]], 1
+; MDEP-NEXT: [[SCEVGEP12:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP11]]
+; MDEP-NEXT: [[TMP4]] = load double, ptr [[SCEVGEP10]], align 8
+; MDEP-NEXT: [[TMP5:%.*]] = fadd double [[TMP3]], [[TMP4]]
+; MDEP-NEXT: [[TMP6]] = fadd double [[TMP5]], [[TMP2]]
+; MDEP-NEXT: store double [[TMP6]], ptr [[SCEVGEP12]], align 8
+; MDEP-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP11]], [[TMP8]]
+; MDEP-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MDEP: return:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test10(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TMP0:%.*]] = add i32 [[N:%.*]], -1
+; MSSA-NEXT: [[TMP1:%.*]] = icmp sgt i32 [[TMP0]], 1
+; MSSA-NEXT: br i1 [[TMP1]], label [[BB_NPH:%.*]], label [[RETURN:%.*]]
+; MSSA: bb.nph:
+; MSSA-NEXT: [[TMP:%.*]] = sext i32 [[TMP0]] to i64
+; MSSA-NEXT: [[TMP8:%.*]] = add i64 [[TMP]], -1
+; MSSA-NEXT: br label [[BB:%.*]]
+; MSSA: bb:
+; MSSA-NEXT: [[INDVAR:%.*]] = phi i64 [ 0, [[BB_NPH]] ], [ [[TMP11:%.*]], [[BB]] ]
+; MSSA-NEXT: [[SCEVGEP:%.*]] = getelementptr double, ptr [[G:%.*]], i64 [[INDVAR]]
+; MSSA-NEXT: [[TMP9:%.*]] = add i64 [[INDVAR]], 2
+; MSSA-NEXT: [[SCEVGEP10:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP9]]
+; MSSA-NEXT: [[TMP11]] = add i64 [[INDVAR]], 1
+; MSSA-NEXT: [[SCEVGEP12:%.*]] = getelementptr double, ptr [[G]], i64 [[TMP11]]
+; MSSA-NEXT: [[TMP2:%.*]] = load double, ptr [[SCEVGEP12]], align 8
+; MSSA-NEXT: [[TMP3:%.*]] = load double, ptr [[SCEVGEP10]], align 8
+; MSSA-NEXT: [[TMP4:%.*]] = fadd double [[TMP2]], [[TMP3]]
+; MSSA-NEXT: [[TMP5:%.*]] = load double, ptr [[SCEVGEP]], align 8
+; MSSA-NEXT: [[TMP6:%.*]] = fadd double [[TMP4]], [[TMP5]]
+; MSSA-NEXT: store double [[TMP6]], ptr [[SCEVGEP12]], align 8
+; MSSA-NEXT: [[EXITCOND:%.*]] = icmp eq i64 [[TMP11]], [[TMP8]]
+; MSSA-NEXT: br i1 [[EXITCOND]], label [[RETURN]], label [[BB]]
+; MSSA: return:
+; MSSA-NEXT: ret void
;
entry:
%0 = add i32 %N, -1
@@ -547,24 +760,40 @@ return:
; Test critical edge splitting.
define i32 @test11(ptr %p, i1 %C, i32 %N) {
-; CHECK-LABEL: @test11(
-; CHECK-NEXT: block1:
-; CHECK-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
-; CHECK: block2:
-; CHECK-NEXT: [[COND:%.*]] = icmp sgt i32 [[N:%.*]], 1
-; CHECK-NEXT: br i1 [[COND]], label [[BLOCK2_BLOCK4_CRIT_EDGE:%.*]], label [[BLOCK5:%.*]]
-; CHECK: block2.block4_crit_edge:
-; CHECK-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
-; CHECK-NEXT: br label [[BLOCK4:%.*]]
-; CHECK: block3:
-; CHECK-NEXT: store i32 0, ptr [[P]], align 4
-; CHECK-NEXT: br label [[BLOCK4]]
-; CHECK: block4:
-; CHECK-NEXT: [[PRE:%.*]] = phi i32 [ [[PRE_PRE]], [[BLOCK2_BLOCK4_CRIT_EDGE]] ], [ 0, [[BLOCK3]] ]
-; CHECK-NEXT: br label [[BLOCK5]]
-; CHECK: block5:
-; CHECK-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BLOCK2]] ], [ [[PRE]], [[BLOCK4]] ]
-; CHECK-NEXT: ret i32 [[RET]]
+; MDEP-LABEL: @test11(
+; MDEP-NEXT: block1:
+; MDEP-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MDEP: block2:
+; MDEP-NEXT: [[COND:%.*]] = icmp sgt i32 [[N:%.*]], 1
+; MDEP-NEXT: br i1 [[COND]], label [[BLOCK2_BLOCK4_CRIT_EDGE:%.*]], label [[BLOCK5:%.*]]
+; MDEP: block2.block4_crit_edge:
+; MDEP-NEXT: [[PRE_PRE:%.*]] = load i32, ptr [[P:%.*]], align 4
+; MDEP-NEXT: br label [[BLOCK4:%.*]]
+; MDEP: block3:
+; MDEP-NEXT: store i32 0, ptr [[P]], align 4
+; MDEP-NEXT: br label [[BLOCK4]]
+; MDEP: block4:
+; MDEP-NEXT: [[PRE:%.*]] = phi i32 [ [[PRE_PRE]], [[BLOCK2_BLOCK4_CRIT_EDGE]] ], [ 0, [[BLOCK3]] ]
+; MDEP-NEXT: br label [[BLOCK5]]
+; MDEP: block5:
+; MDEP-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BLOCK2]] ], [ [[PRE]], [[BLOCK4]] ]
+; MDEP-NEXT: ret i32 [[RET]]
+;
+; MSSA-LABEL: @test11(
+; MSSA-NEXT: block1:
+; MSSA-NEXT: br i1 [[C:%.*]], label [[BLOCK2:%.*]], label [[BLOCK3:%.*]]
+; MSSA: block2:
+; MSSA-NEXT: [[COND:%.*]] = icmp sgt i32 [[N:%.*]], 1
+; MSSA-NEXT: br i1 [[COND]], label [[BLOCK4:%.*]], label [[BLOCK5:%.*]]
+; MSSA: block3:
+; MSSA-NEXT: store i32 0, ptr [[P:%.*]], align 4
+; MSSA-NEXT: br label [[BLOCK4]]
+; MSSA: block4:
+; MSSA-NEXT: [[PRE:%.*]] = load i32, ptr [[P]], align 4
+; MSSA-NEXT: br label [[BLOCK5]]
+; MSSA: block5:
+; MSSA-NEXT: [[RET:%.*]] = phi i32 [ 0, [[BLOCK2]] ], [ [[PRE]], [[BLOCK4]] ]
+; MSSA-NEXT: ret i32 [[RET]]
;
block1:
br i1 %C, label %block2, label %block3
@@ -726,17 +955,30 @@ follow_2:
; Since it is OK to speculate, PRE is allowed.
define i32 @test15(ptr noalias nocapture readonly dereferenceable(8) align 4 %x, ptr noalias nocapture %r, i32 %a) nofree nosync {
-; CHECK-LABEL: @test15(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
-; CHECK-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: call void @f()
-; CHECK-NEXT: ret i32 [[VV_PRE]]
+; MDEP-LABEL: @test15(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
+; MDEP-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4
+; MDEP-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: call void @f()
+; MDEP-NEXT: ret i32 [[VV_PRE]]
+;
+; MSSA-LABEL: @test15(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
+; MSSA-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[UU:%.*]] = load i32, ptr [[X:%.*]], align 4
+; MSSA-NEXT: store i32 [[UU]], ptr [[R:%.*]], align 4
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: call void @f()
+; MSSA-NEXT: [[VV:%.*]] = load i32, ptr [[X]], align 4
+; MSSA-NEXT: ret i32 [[VV]]
;
entry:
@@ -763,17 +1005,30 @@ if.end:
; Since it is OK to speculate, PRE is allowed.
define i32 @test16(ptr noalias nocapture readonly dereferenceable(8) align 4 %x, ptr noalias nocapture %r, i32 %a) nofree nosync {
-; CHECK-LABEL: @test16(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
-; CHECK-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4
-; CHECK-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: call void @f()
-; CHECK-NEXT: ret i32 [[VV_PRE]]
+; MDEP-LABEL: @test16(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
+; MDEP-NEXT: [[VV_PRE:%.*]] = load i32, ptr [[X:%.*]], align 4
+; MDEP-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: store i32 [[VV_PRE]], ptr [[R:%.*]], align 4
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: call void @f()
+; MDEP-NEXT: ret i32 [[VV_PRE]]
+;
+; MSSA-LABEL: @test16(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[TOBOOL:%.*]] = icmp eq i32 [[A:%.*]], 0
+; MSSA-NEXT: br i1 [[TOBOOL]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[UU:%.*]] = load i32, ptr [[X:%.*]], align 4
+; MSSA-NEXT: store i32 [[UU]], ptr [[R:%.*]], align 4
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: call void @f()
+; MSSA-NEXT: [[VV:%.*]] = load i32, ptr [[X]], align 4
+; MSSA-NEXT: ret i32 [[VV]]
;
entry:
@@ -808,36 +1063,67 @@ declare i1 @bar()
; We can move all loads into predecessors.
define void @test17(ptr %p1, ptr %p2, ptr %p3, ptr %p4)
-; CHECK-LABEL: @test17(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8
-; CHECK-NEXT: [[COND1:%.*]] = icmp sgt i64 [[V1]], 200
-; CHECK-NEXT: br i1 [[COND1]], label [[BB200:%.*]], label [[BB1:%.*]]
-; CHECK: bb1:
-; CHECK-NEXT: [[COND2:%.*]] = icmp sgt i64 [[V1]], 100
-; CHECK-NEXT: br i1 [[COND2]], label [[BB100:%.*]], label [[BB2:%.*]]
-; CHECK: bb2:
-; CHECK-NEXT: [[V2:%.*]] = add nsw i64 [[V1]], 1
-; CHECK-NEXT: store i64 [[V2]], ptr [[P1]], align 8
-; CHECK-NEXT: br label [[BB3:%.*]]
-; CHECK: bb3:
-; CHECK-NEXT: [[V3:%.*]] = phi i64 [ [[V3_PRE:%.*]], [[BB200]] ], [ [[V3_PRE1:%.*]], [[BB100]] ], [ [[V2]], [[BB2]] ]
-; CHECK-NEXT: store i64 [[V3]], ptr [[P2:%.*]], align 8
-; CHECK-NEXT: ret void
-; CHECK: bb100:
-; CHECK-NEXT: [[COND3:%.*]] = call i1 @foo()
-; CHECK-NEXT: [[V3_PRE1]] = load i64, ptr [[P1]], align 8
-; CHECK-NEXT: br i1 [[COND3]], label [[BB3]], label [[BB101:%.*]]
-; CHECK: bb101:
-; CHECK-NEXT: store i64 [[V3_PRE1]], ptr [[P3:%.*]], align 8
-; CHECK-NEXT: ret void
-; CHECK: bb200:
-; CHECK-NEXT: [[COND4:%.*]] = call i1 @bar()
-; CHECK-NEXT: [[V3_PRE]] = load i64, ptr [[P1]], align 8
-; CHECK-NEXT: br i1 [[COND4]], label [[BB3]], label [[BB201:%.*]]
-; CHECK: bb201:
-; CHECK-NEXT: store i64 [[V3_PRE]], ptr [[P4:%.*]], align 8
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test17(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8
+; MDEP-NEXT: [[COND1:%.*]] = icmp sgt i64 [[V1]], 200
+; MDEP-NEXT: br i1 [[COND1]], label [[BB200:%.*]], label [[BB1:%.*]]
+; MDEP: bb1:
+; MDEP-NEXT: [[COND2:%.*]] = icmp sgt i64 [[V1]], 100
+; MDEP-NEXT: br i1 [[COND2]], label [[BB100:%.*]], label [[BB2:%.*]]
+; MDEP: bb2:
+; MDEP-NEXT: [[V2:%.*]] = add nsw i64 [[V1]], 1
+; MDEP-NEXT: store i64 [[V2]], ptr [[P1]], align 8
+; MDEP-NEXT: br label [[BB3:%.*]]
+; MDEP: bb3:
+; MDEP-NEXT: [[V3:%.*]] = phi i64 [ [[V3_PRE:%.*]], [[BB200]] ], [ [[V3_PRE1:%.*]], [[BB100]] ], [ [[V2]], [[BB2]] ]
+; MDEP-NEXT: store i64 [[V3]], ptr [[P2:%.*]], align 8
+; MDEP-NEXT: ret void
+; MDEP: bb100:
+; MDEP-NEXT: [[COND3:%.*]] = call i1 @foo()
+; MDEP-NEXT: [[V3_PRE1]] = load i64, ptr [[P1]], align 8
+; MDEP-NEXT: br i1 [[COND3]], label [[BB3]], label [[BB101:%.*]]
+; MDEP: bb101:
+; MDEP-NEXT: store i64 [[V3_PRE1]], ptr [[P3:%.*]], align 8
+; MDEP-NEXT: ret void
+; MDEP: bb200:
+; MDEP-NEXT: [[COND4:%.*]] = call i1 @bar()
+; MDEP-NEXT: [[V3_PRE]] = load i64, ptr [[P1]], align 8
+; MDEP-NEXT: br i1 [[COND4]], label [[BB3]], label [[BB201:%.*]]
+; MDEP: bb201:
+; MDEP-NEXT: store i64 [[V3_PRE]], ptr [[P4:%.*]], align 8
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test17(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8
+; MSSA-NEXT: [[COND1:%.*]] = icmp sgt i64 [[V1]], 200
+; MSSA-NEXT: br i1 [[COND1]], label [[BB200:%.*]], label [[BB1:%.*]]
+; MSSA: bb1:
+; MSSA-NEXT: [[COND2:%.*]] = icmp sgt i64 [[V1]], 100
+; MSSA-NEXT: br i1 [[COND2]], label [[BB100:%.*]], label [[BB2:%.*]]
+; MSSA: bb2:
+; MSSA-NEXT: [[V2:%.*]] = add nsw i64 [[V1]], 1
+; MSSA-NEXT: store i64 [[V2]], ptr [[P1]], align 8
+; MSSA-NEXT: br label [[BB3:%.*]]
+; MSSA: bb3:
+; MSSA-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: store i64 [[V3]], ptr [[P2:%.*]], align 8
+; MSSA-NEXT: ret void
+; MSSA: bb100:
+; MSSA-NEXT: [[COND3:%.*]] = call i1 @foo()
+; MSSA-NEXT: br i1 [[COND3]], label [[BB3]], label [[BB101:%.*]]
+; MSSA: bb101:
+; MSSA-NEXT: [[V4:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: store i64 [[V4]], ptr [[P3:%.*]], align 8
+; MSSA-NEXT: ret void
+; MSSA: bb200:
+; MSSA-NEXT: [[COND4:%.*]] = call i1 @bar()
+; MSSA-NEXT: br i1 [[COND4]], label [[BB3]], label [[BB201:%.*]]
+; MSSA: bb201:
+; MSSA-NEXT: [[V5:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: store i64 [[V5]], ptr [[P4:%.*]], align 8
+; MSSA-NEXT: ret void
;
{
entry:
@@ -882,18 +1168,31 @@ bb201:
; So ValuesPerBlock[%if.then] should not be replaced when the load instruction
; is moved to %entry.
define void @test18(i1 %cond, ptr %p1, ptr %p2) {
-; CHECK-LABEL: @test18(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[V2_PRE:%.*]] = load i16, ptr [[P1:%.*]], align 2
-; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[DEC:%.*]] = add i16 [[V2_PRE]], -1
-; CHECK-NEXT: store i16 [[DEC]], ptr [[P1]], align 2
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: if.end:
-; CHECK-NEXT: [[V2:%.*]] = phi i16 [ [[DEC]], [[IF_THEN]] ], [ [[V2_PRE]], [[ENTRY:%.*]] ]
-; CHECK-NEXT: store i16 [[V2]], ptr [[P2:%.*]], align 2
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test18(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[V2_PRE:%.*]] = load i16, ptr [[P1:%.*]], align 2
+; MDEP-NEXT: br i1 [[COND:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: [[DEC:%.*]] = add i16 [[V2_PRE]], -1
+; MDEP-NEXT: store i16 [[DEC]], ptr [[P1]], align 2
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: if.end:
+; MDEP-NEXT: [[V2:%.*]] = phi i16 [ [[DEC]], [[IF_THEN]] ], [ [[V2_PRE]], [[ENTRY:%.*]] ]
+; MDEP-NEXT: store i16 [[V2]], ptr [[P2:%.*]], align 2
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test18(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: br i1 [[COND:%.*]], label [[IF_END:%.*]], label [[IF_THEN:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[V1:%.*]] = load i16, ptr [[P1:%.*]], align 2
+; MSSA-NEXT: [[DEC:%.*]] = add i16 [[V1]], -1
+; MSSA-NEXT: store i16 [[DEC]], ptr [[P1]], align 2
+; MSSA-NEXT: br label [[IF_END]]
+; MSSA: if.end:
+; MSSA-NEXT: [[V2:%.*]] = load i16, ptr [[P1]], align 2
+; MSSA-NEXT: store i16 [[V2]], ptr [[P2:%.*]], align 2
+; MSSA-NEXT: ret void
;
entry:
br i1 %cond, label %if.end, label %if.then
@@ -912,32 +1211,56 @@ if.end:
; PRE of load instructions should not cross exception handling instructions.
define void @test19(i1 %cond, ptr %p1, ptr %p2)
-; CHECK-LABEL: @test19(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
-; CHECK: then:
-; CHECK-NEXT: [[V2:%.*]] = load i64, ptr [[P2:%.*]], align 8
-; CHECK-NEXT: [[ADD:%.*]] = add i64 [[V2]], 1
-; CHECK-NEXT: store i64 [[ADD]], ptr [[P1:%.*]], align 8
-; CHECK-NEXT: br label [[END:%.*]]
-; CHECK: else:
-; CHECK-NEXT: invoke void @f()
-; CHECK-NEXT: to label [[ELSE_END_CRIT_EDGE:%.*]] unwind label [[LPAD:%.*]]
-; CHECK: else.end_crit_edge:
-; CHECK-NEXT: [[V1_PRE:%.*]] = load i64, ptr [[P1]], align 8
-; CHECK-NEXT: br label [[END]]
-; CHECK: end:
-; CHECK-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ELSE_END_CRIT_EDGE]] ], [ [[ADD]], [[THEN]] ]
-; CHECK-NEXT: [[AND:%.*]] = and i64 [[V1]], 100
-; CHECK-NEXT: store i64 [[AND]], ptr [[P2]], align 8
-; CHECK-NEXT: ret void
-; CHECK: lpad:
-; CHECK-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
-; CHECK-NEXT: cleanup
-; CHECK-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
-; CHECK-NEXT: [[OR:%.*]] = or i64 [[V3]], 200
-; CHECK-NEXT: store i64 [[OR]], ptr [[P1]], align 8
-; CHECK-NEXT: resume { ptr, i32 } [[LP]]
+; MDEP-LABEL: @test19(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; MDEP: then:
+; MDEP-NEXT: [[V2:%.*]] = load i64, ptr [[P2:%.*]], align 8
+; MDEP-NEXT: [[ADD:%.*]] = add i64 [[V2]], 1
+; MDEP-NEXT: store i64 [[ADD]], ptr [[P1:%.*]], align 8
+; MDEP-NEXT: br label [[END:%.*]]
+; MDEP: else:
+; MDEP-NEXT: invoke void @f()
+; MDEP-NEXT: to label [[ELSE_END_CRIT_EDGE:%.*]] unwind label [[LPAD:%.*]]
+; MDEP: else.end_crit_edge:
+; MDEP-NEXT: [[V1_PRE:%.*]] = load i64, ptr [[P1]], align 8
+; MDEP-NEXT: br label [[END]]
+; MDEP: end:
+; MDEP-NEXT: [[V1:%.*]] = phi i64 [ [[V1_PRE]], [[ELSE_END_CRIT_EDGE]] ], [ [[ADD]], [[THEN]] ]
+; MDEP-NEXT: [[AND:%.*]] = and i64 [[V1]], 100
+; MDEP-NEXT: store i64 [[AND]], ptr [[P2]], align 8
+; MDEP-NEXT: ret void
+; MDEP: lpad:
+; MDEP-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
+; MDEP-NEXT: cleanup
+; MDEP-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
+; MDEP-NEXT: [[OR:%.*]] = or i64 [[V3]], 200
+; MDEP-NEXT: store i64 [[OR]], ptr [[P1]], align 8
+; MDEP-NEXT: resume { ptr, i32 } [[LP]]
+;
+; MSSA-LABEL: @test19(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: br i1 [[COND:%.*]], label [[THEN:%.*]], label [[ELSE:%.*]]
+; MSSA: then:
+; MSSA-NEXT: [[V2:%.*]] = load i64, ptr [[P2:%.*]], align 8
+; MSSA-NEXT: [[ADD:%.*]] = add i64 [[V2]], 1
+; MSSA-NEXT: store i64 [[ADD]], ptr [[P1:%.*]], align 8
+; MSSA-NEXT: br label [[END:%.*]]
+; MSSA: else:
+; MSSA-NEXT: invoke void @f()
+; MSSA-NEXT: to label [[END]] unwind label [[LPAD:%.*]]
+; MSSA: end:
+; MSSA-NEXT: [[V1:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: [[AND:%.*]] = and i64 [[V1]], 100
+; MSSA-NEXT: store i64 [[AND]], ptr [[P2]], align 8
+; MSSA-NEXT: ret void
+; MSSA: lpad:
+; MSSA-NEXT: [[LP:%.*]] = landingpad { ptr, i32 }
+; MSSA-NEXT: cleanup
+; MSSA-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: [[OR:%.*]] = or i64 [[V3]], 200
+; MSSA-NEXT: store i64 [[OR]], ptr [[P1]], align 8
+; MSSA-NEXT: resume { ptr, i32 } [[LP]]
;
personality ptr @__CxxFrameHandler3 {
entry:
@@ -1050,29 +1373,50 @@ if.end:
; Call to function @maybethrow may cause exception, so the load of %v3 can't
; be hoisted to block %if.else.
define void @test22(i1 %cond, ptr %p1, ptr %p2) {
-; CHECK-LABEL: @test22(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
-; CHECK: if.then:
-; CHECK-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8
-; CHECK-NEXT: [[DEC:%.*]] = add i64 [[V1]], -1
-; CHECK-NEXT: store i64 [[DEC]], ptr [[P1]], align 8
-; CHECK-NEXT: br label [[IF_END:%.*]]
-; CHECK: if.end:
-; CHECK-NEXT: [[V2:%.*]] = phi i64 [ [[V2_PRE:%.*]], [[IF_ELSE_IF_END_CRIT_EDGE:%.*]] ], [ [[DEC]], [[IF_THEN]] ]
-; CHECK-NEXT: store i64 [[V2]], ptr [[P2:%.*]], align 8
-; CHECK-NEXT: ret void
-; CHECK: if.else:
-; CHECK-NEXT: [[COND2:%.*]] = call i1 @foo()
-; CHECK-NEXT: br i1 [[COND2]], label [[IF_ELSE_IF_END_CRIT_EDGE]], label [[EXIT:%.*]]
-; CHECK: if.else.if.end_crit_edge:
-; CHECK-NEXT: [[V2_PRE]] = load i64, ptr [[P1]], align 8
-; CHECK-NEXT: br label [[IF_END]]
-; CHECK: exit:
-; CHECK-NEXT: [[_:%.*]] = call i1 @maybethrow()
-; CHECK-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
-; CHECK-NEXT: store i64 [[V3]], ptr [[P2]], align 8
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test22(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; MDEP: if.then:
+; MDEP-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8
+; MDEP-NEXT: [[DEC:%.*]] = add i64 [[V1]], -1
+; MDEP-NEXT: store i64 [[DEC]], ptr [[P1]], align 8
+; MDEP-NEXT: br label [[IF_END:%.*]]
+; MDEP: if.end:
+; MDEP-NEXT: [[V2:%.*]] = phi i64 [ [[V2_PRE:%.*]], [[IF_ELSE_IF_END_CRIT_EDGE:%.*]] ], [ [[DEC]], [[IF_THEN]] ]
+; MDEP-NEXT: store i64 [[V2]], ptr [[P2:%.*]], align 8
+; MDEP-NEXT: ret void
+; MDEP: if.else:
+; MDEP-NEXT: [[COND2:%.*]] = call i1 @foo()
+; MDEP-NEXT: br i1 [[COND2]], label [[IF_ELSE_IF_END_CRIT_EDGE]], label [[EXIT:%.*]]
+; MDEP: if.else.if.end_crit_edge:
+; MDEP-NEXT: [[V2_PRE]] = load i64, ptr [[P1]], align 8
+; MDEP-NEXT: br label [[IF_END]]
+; MDEP: exit:
+; MDEP-NEXT: [[_:%.*]] = call i1 @maybethrow()
+; MDEP-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
+; MDEP-NEXT: store i64 [[V3]], ptr [[P2]], align 8
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test22(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: br i1 [[COND:%.*]], label [[IF_THEN:%.*]], label [[IF_ELSE:%.*]]
+; MSSA: if.then:
+; MSSA-NEXT: [[V1:%.*]] = load i64, ptr [[P1:%.*]], align 8
+; MSSA-NEXT: [[DEC:%.*]] = add i64 [[V1]], -1
+; MSSA-NEXT: store i64 [[DEC]], ptr [[P1]], align 8
+; MSSA-NEXT: br label [[IF_END:%.*]]
+; MSSA: if.end:
+; MSSA-NEXT: [[V2:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: store i64 [[V2]], ptr [[P2:%.*]], align 8
+; MSSA-NEXT: ret void
+; MSSA: if.else:
+; MSSA-NEXT: [[COND2:%.*]] = call i1 @foo()
+; MSSA-NEXT: br i1 [[COND2]], label [[IF_END]], label [[EXIT:%.*]]
+; MSSA: exit:
+; MSSA-NEXT: [[_:%.*]] = call i1 @maybethrow()
+; MSSA-NEXT: [[V3:%.*]] = load i64, ptr [[P1]], align 8
+; MSSA-NEXT: store i64 [[V3]], ptr [[P2]], align 8
+; MSSA-NEXT: ret void
;
entry:
br i1 %cond, label %if.then, label %if.else
@@ -1106,21 +1450,38 @@ declare void @maybethrow() readnone
; also be replaced by ValuesPerBlock(BB, NewLoad). So we'll not use the deleted
; OldLoad in later PHI instruction.
define void @test23(i1 %cond1, i1 %cond2) {
-; CHECK-LABEL: @test23(
-; CHECK-NEXT: entry:
-; CHECK-NEXT: [[G:%.*]] = alloca i64, align 8
-; CHECK-NEXT: [[VAL1_PRE:%.*]] = load i64, ptr @B, align 8
-; CHECK-NEXT: br i1 [[COND2:%.*]], label [[THEN:%.*]], label [[WRONG:%.*]]
-; CHECK: then:
-; CHECK-NEXT: br i1 [[COND1:%.*]], label [[STORE:%.*]], label [[EXIT:%.*]]
-; CHECK: store:
-; CHECK-NEXT: store i64 [[VAL1_PRE]], ptr @B, align 8
-; CHECK-NEXT: br label [[WRONG]]
-; CHECK: wrong:
-; CHECK-NEXT: store i64 [[VAL1_PRE]], ptr [[G]], align 8
-; CHECK-NEXT: ret void
-; CHECK: exit:
-; CHECK-NEXT: ret void
+; MDEP-LABEL: @test23(
+; MDEP-NEXT: entry:
+; MDEP-NEXT: [[G:%.*]] = alloca i64, align 8
+; MDEP-NEXT: [[VAL1_PRE:%.*]] = load i64, ptr @B, align 8
+; MDEP-NEXT: br i1 [[COND2:%.*]], label [[THEN:%.*]], label [[WRONG:%.*]]
+; MDEP: then:
+; MDEP-NEXT: br i1 [[COND1:%.*]], label [[STORE:%.*]], label [[EXIT:%.*]]
+; MDEP: store:
+; MDEP-NEXT: store i64 [[VAL1_PRE]], ptr @B, align 8
+; MDEP-NEXT: br label [[WRONG]]
+; MDEP: wrong:
+; MDEP-NEXT: store i64 [[VAL1_PRE]], ptr [[G]], align 8
+; MDEP-NEXT: ret void
+; MDEP: exit:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: @test23(
+; MSSA-NEXT: entry:
+; MSSA-NEXT: [[G:%.*]] = alloca i64, align 8
+; MSSA-NEXT: br i1 [[COND2:%.*]], label [[THEN:%.*]], label [[WRONG:%.*]]
+; MSSA: then:
+; MSSA-NEXT: [[VAL2:%.*]] = load i64, ptr @B, align 8
+; MSSA-NEXT: br i1 [[COND1:%.*]], label [[STORE:%.*]], label [[EXIT:%.*]]
+; MSSA: store:
+; MSSA-NEXT: store i64 [[VAL2]], ptr @B, align 8
+; MSSA-NEXT: br label [[WRONG]]
+; MSSA: wrong:
+; MSSA-NEXT: [[VAL1:%.*]] = load i64, ptr @B, align 8
+; MSSA-NEXT: store i64 [[VAL1]], ptr [[G]], align 8
+; MSSA-NEXT: ret void
+; MSSA: exit:
+; MSSA-NEXT: ret void
;
entry:
%G = alloca i64, align 8
diff --git a/llvm/test/Transforms/GVN/PRE/pre-loop-load-new-pm.ll b/llvm/test/Transforms/GVN/PRE/pre-loop-load-new-pm.ll
index e16c21e516eb5..4cd2e47b3c31f 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-loop-load-new-pm.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-loop-load-new-pm.ll
@@ -1,5 +1,6 @@
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
-; RUN: opt -aa-pipeline=basic-aa -enable-load-pre -enable-pre -passes=gvn -S < %s | FileCheck %s
+; RUN: opt -aa-pipeline=basic-aa -enable-load-pre -enable-pre -passes=gvn -S < %s | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt -aa-pipeline=basic-aa -enable-load-pre -enable-pre -passes='gvn<memoryssa>' -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA
declare void @side_effect()
declare i1 @side_effect_cond()
@@ -216,7 +217,7 @@ define i32 @test_load_on_exiting_cold_path_02(ptr %p) gc "statepoint-example" pe
; CHECK-NEXT: br label [[BACKEDGE]]
; CHECK: cold_path:
; CHECK-NEXT: invoke void @side_effect()
-; CHECK-NEXT: to label [[BACKEDGE]] unwind label [[COLD_EXIT:%.*]]
+; CHECK-NEXT: to label [[BACKEDGE]] unwind label [[COLD_EXIT:%.*]]
; CHECK: backedge:
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
@@ -225,7 +226,7 @@ define i32 @test_load_on_exiting_cold_path_02(ptr %p) gc "statepoint-example" pe
; CHECK-NEXT: ret i32 [[X]]
; CHECK: cold_exit:
; CHECK-NEXT: [[LANDING_PAD:%.*]] = landingpad token
-; CHECK-NEXT: cleanup
+; CHECK-NEXT: cleanup
; CHECK-NEXT: ret i32 -1
;
entry:
@@ -447,7 +448,7 @@ define i32 @test_inner_loop(ptr %p, i1 %arg) {
; CHECK-NEXT: br label [[INNER_LOOP:%.*]]
; CHECK: inner_loop:
; CHECK-NEXT: call void @side_effect()
-; CHECK-NEXT: br i1 %arg, label [[INNER_LOOP]], label [[BACKEDGE]]
+; CHECK-NEXT: br i1 [[ARG:%.*]], label [[INNER_LOOP]], label [[BACKEDGE]]
; CHECK: backedge:
; CHECK-NEXT: [[IV_NEXT]] = add i32 [[IV]], [[X]]
; CHECK-NEXT: [[LOOP_COND:%.*]] = icmp ult i32 [[IV_NEXT]], 1000
@@ -633,3 +634,6 @@ exit:
cold_exit:
ret i32 -1
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
+; MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-no-cost-phi.ll b/llvm/test/Transforms/GVN/PRE/pre-no-cost-phi.ll
index 2009c29931455..22c628bb35464 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-no-cost-phi.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-no-cost-phi.ll
@@ -1,4 +1,6 @@
-; RUN: opt < %s -passes=gvn -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -S | FileCheck %s --check-prefixes=CHECK,MSSA
; This testcase tests insertion of no-cost phis. That is,
; when the value is already available in every predecessor,
; and we just need to insert a phi node to merge the available values.
@@ -8,6 +10,22 @@
define i32 @mai(i32 %foo, i32 %a, i32 %b) {
+; CHECK-LABEL: define i32 @mai(
+; CHECK-SAME: i32 [[FOO:%.*]], i32 [[A:%.*]], i32 [[B:%.*]]) {
+; CHECK-NEXT: [[TMP1:%.*]] = icmp ne i32 [[FOO]], 0
+; CHECK-NEXT: br i1 [[TMP1]], label %[[BB1:.*]], label %[[BB2:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[TMP2:%.*]] = add nsw i32 [[A]], [[B]]
+; CHECK-NEXT: store i32 [[TMP2]], ptr @c, align 4
+; CHECK-NEXT: br label %[[MERGEBLOCK:.*]]
+; CHECK: [[BB2]]:
+; CHECK-NEXT: [[TMP3:%.*]] = add nsw i32 [[A]], [[B]]
+; CHECK-NEXT: store i32 [[TMP3]], ptr @d, align 4
+; CHECK-NEXT: br label %[[MERGEBLOCK]]
+; CHECK: [[MERGEBLOCK]]:
+; CHECK-NEXT: [[DOTPRE_PHI:%.*]] = phi i32 [ [[TMP3]], %[[BB2]] ], [ [[TMP2]], %[[BB1]] ]
+; CHECK-NEXT: ret i32 [[DOTPRE_PHI]]
+;
%1 = icmp ne i32 %foo, 0
br i1 %1, label %bb1, label %bb2
@@ -22,10 +40,11 @@ bb2:
br label %mergeblock
mergeblock:
-; CHECK: pre-phi = phi i32 [ %3, %bb2 ], [ %2, %bb1 ]
-; CHECK-NEXT: ret i32 %.pre-phi
%4 = add nsw i32 %a, %b
ret i32 %4
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
+; MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-poison-add.ll b/llvm/test/Transforms/GVN/PRE/pre-poison-add.ll
index d17c459f1cff8..32f149b881d72 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-poison-add.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-poison-add.ll
@@ -1,52 +1,77 @@
-; RUN: opt < %s -passes=gvn -enable-pre -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn -enable-pre -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -enable-pre -S | FileCheck %s --check-prefixes=CHECK,MSSA
@H = common global i32 0
@G = common global i32 0
define i32 @test1(i1 %cond, i32 %v) nounwind {
-; CHECK-LABEL: @test1
+; CHECK-LABEL: define i32 @test1(
+; CHECK-SAME: i1 [[COND:%.*]], i32 [[V:%.*]]) #[[ATTR0:[0-9]+]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br i1 [[COND]], label %[[BB:.*]], label %[[BB1:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[V]], 42
+; CHECK-NEXT: store i32 [[ADD_1]], ptr @G, align 4
+; CHECK-NEXT: br label %[[RETURN:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[DOTPRE:%.*]] = add i32 [[V]], 42
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[ADD_2_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE]], %[[BB1]] ], [ [[ADD_1]], %[[BB]] ]
+; CHECK-NEXT: store i32 [[ADD_2_PRE_PHI]], ptr @H, align 4
+; CHECK-NEXT: ret i32 0
+;
entry:
- br i1 %cond, label %bb, label %bb1
+ br i1 %cond, label %bb, label %bb1
bb:
- %add.1 = add nuw nsw i32 %v, 42
-; CHECK: %add.1 = add i32 %v, 42
- store i32 %add.1, ptr @G, align 4
- br label %return
+ %add.1 = add nuw nsw i32 %v, 42
+ store i32 %add.1, ptr @G, align 4
+ br label %return
bb1:
-; CHECK: %.pre = add i32 %v, 42
- br label %return
+ br label %return
return:
-; CHECK: %add.2.pre-phi = phi i32 [ %.pre, %bb1 ], [ %add.1, %bb ]
-; CHECK-NEXT: store i32 %add.2.pre-phi, ptr @H, align 4
-; CHECK-NEXT: ret i32 0
- %add.2 = add i32 %v, 42
- store i32 %add.2, ptr @H, align 4
- ret i32 0
+ %add.2 = add i32 %v, 42
+ store i32 %add.2, ptr @H, align 4
+ ret i32 0
}
define i32 @test2(i1 %cond, i32 %v) nounwind {
-; CHECK-LABEL: @test2
+; CHECK-LABEL: define i32 @test2(
+; CHECK-SAME: i1 [[COND:%.*]], i32 [[V:%.*]]) #[[ATTR0]] {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: br i1 [[COND]], label %[[BB:.*]], label %[[BB1:.*]]
+; CHECK: [[BB]]:
+; CHECK-NEXT: [[ADD_1:%.*]] = add i32 [[V]], 42
+; CHECK-NEXT: store i32 [[ADD_1]], ptr @G, align 4
+; CHECK-NEXT: br label %[[RETURN:.*]]
+; CHECK: [[BB1]]:
+; CHECK-NEXT: [[DOTPRE:%.*]] = add nuw nsw i32 [[V]], 42
+; CHECK-NEXT: br label %[[RETURN]]
+; CHECK: [[RETURN]]:
+; CHECK-NEXT: [[ADD_2_PRE_PHI:%.*]] = phi i32 [ [[DOTPRE]], %[[BB1]] ], [ [[ADD_1]], %[[BB]] ]
+; CHECK-NEXT: store i32 [[ADD_2_PRE_PHI]], ptr @H, align 4
+; CHECK-NEXT: ret i32 0
+;
entry:
- br i1 %cond, label %bb, label %bb1
+ br i1 %cond, label %bb, label %bb1
bb:
- %add.1 = add i32 %v, 42
-; CHECK: %add.1 = add i32 %v, 42
- store i32 %add.1, ptr @G, align 4
- br label %return
+ %add.1 = add i32 %v, 42
+ store i32 %add.1, ptr @G, align 4
+ br label %return
bb1:
-; CHECK: %.pre = add nuw nsw i32 %v, 42
- br label %return
+ br label %return
return:
-; CHECK: %add.2.pre-phi = phi i32 [ %.pre, %bb1 ], [ %add.1, %bb ]
-; CHECK-NEXT: store i32 %add.2.pre-phi, ptr @H, align 4
-; CHECK-NEXT: ret i32 0
- %add.2 = add nuw nsw i32 %v, 42
- store i32 %add.2, ptr @H, align 4
- ret i32 0
+ %add.2 = add nuw nsw i32 %v, 42
+ store i32 %add.2, ptr @H, align 4
+ ret i32 0
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; MDEP: {{.*}}
+; MSSA: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll b/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll
index 7342925a0c3be..74bc6bcaecf67 100644
--- a/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll
+++ b/llvm/test/Transforms/GVN/PRE/pre-single-pred.ll
@@ -1,4 +1,6 @@
-; RUN: opt < %s -passes=gvn -enable-load-pre -S | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt < %s -passes=gvn -enable-load-pre -S | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt < %s -passes='gvn<memoryssa>' -enable-load-pre -S | FileCheck %s --check-prefixes=CHECK,MSSA
; RUN: opt < %s -passes="gvn<load-pre>" -enable-load-pre=false -S | FileCheck %s
; This testcase assumed we'll PRE the load into %for.cond, but we don't actually
; verify that doing so is safe. If there didn't _happen_ to be a load in
@@ -12,35 +14,85 @@
@p = external global i32
define i32 @f(i32 %n) nounwind {
+; MDEP-LABEL: define i32 @f(
+; MDEP-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; MDEP-NEXT: [[ENTRY:.*]]:
+; MDEP-NEXT: br label %[[FOR_COND:.*]]
+; MDEP: [[FOR_COND]]:
+; MDEP-NEXT: [[I_0:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; MDEP-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]]
+; MDEP-NEXT: br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_COND_FOR_END_CRIT_EDGE:.*]]
+; MDEP: [[FOR_COND_FOR_END_CRIT_EDGE]]:
+; MDEP-NEXT: [[TMP9_PRE:%.*]] = load i32, ptr @p, align 4
+; MDEP-NEXT: br label %[[FOR_END:.*]]
+; MDEP: [[FOR_BODY]]:
+; MDEP-NEXT: [[TMP3:%.*]] = load i32, ptr @p, align 4
+; MDEP-NEXT: [[DEC:%.*]] = add i32 [[TMP3]], -1
+; MDEP-NEXT: store i32 [[DEC]], ptr @p, align 4
+; MDEP-NEXT: [[CMP6:%.*]] = icmp slt i32 [[DEC]], 0
+; MDEP-NEXT: br i1 [[CMP6]], label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_INC]]
+; MDEP: [[FOR_BODY_FOR_END_CRIT_EDGE]]:
+; MDEP-NEXT: br label %[[FOR_END]]
+; MDEP: [[FOR_INC]]:
+; MDEP-NEXT: [[INDVAR_NEXT]] = add i32 [[I_0]], 1
+; MDEP-NEXT: br label %[[FOR_COND]]
+; MDEP: [[FOR_END]]:
+; MDEP-NEXT: [[TMP9:%.*]] = phi i32 [ [[DEC]], %[[FOR_BODY_FOR_END_CRIT_EDGE]] ], [ [[TMP9_PRE]], %[[FOR_COND_FOR_END_CRIT_EDGE]] ]
+; MDEP-NEXT: ret i32 [[TMP9]]
+;
+; MSSA-LABEL: define i32 @f(
+; MSSA-SAME: i32 [[N:%.*]]) #[[ATTR0:[0-9]+]] {
+; MSSA-NEXT: [[ENTRY:.*]]:
+; MSSA-NEXT: br label %[[FOR_COND:.*]]
+; MSSA: [[FOR_COND]]:
+; MSSA-NEXT: [[I_0:%.*]] = phi i32 [ 0, %[[ENTRY]] ], [ [[INDVAR_NEXT:%.*]], %[[FOR_INC:.*]] ]
+; MSSA-NEXT: [[CMP:%.*]] = icmp slt i32 [[I_0]], [[N]]
+; MSSA-NEXT: br i1 [[CMP]], label %[[FOR_BODY:.*]], label %[[FOR_COND_FOR_END_CRIT_EDGE:.*]]
+; MSSA: [[FOR_COND_FOR_END_CRIT_EDGE]]:
+; MSSA-NEXT: br label %[[FOR_END:.*]]
+; MSSA: [[FOR_BODY]]:
+; MSSA-NEXT: [[TMP3:%.*]] = load i32, ptr @p, align 4
+; MSSA-NEXT: [[DEC:%.*]] = add i32 [[TMP3]], -1
+; MSSA-NEXT: store i32 [[DEC]], ptr @p, align 4
+; MSSA-NEXT: [[CMP6:%.*]] = icmp slt i32 [[DEC]], 0
+; MSSA-NEXT: br i1 [[CMP6]], label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_INC]]
+; MSSA: [[FOR_BODY_FOR_END_CRIT_EDGE]]:
+; MSSA-NEXT: br label %[[FOR_END]]
+; MSSA: [[FOR_INC]]:
+; MSSA-NEXT: [[INDVAR_NEXT]] = add i32 [[I_0]], 1
+; MSSA-NEXT: br label %[[FOR_COND]]
+; MSSA: [[FOR_END]]:
+; MSSA-NEXT: [[TMP9:%.*]] = load i32, ptr @p, align 4
+; MSSA-NEXT: ret i32 [[TMP9]]
+;
entry:
- br label %for.cond
+ br label %for.cond
for.cond: ; preds = %for.inc, %entry
- %i.0 = phi i32 [ 0, %entry ], [ %indvar.next, %for.inc ] ; <i32> [#uses=2]
- %cmp = icmp slt i32 %i.0, %n ; <i1> [#uses=1]
- br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
+ %i.0 = phi i32 [ 0, %entry ], [ %indvar.next, %for.inc ] ; <i32> [#uses=2]
+ %cmp = icmp slt i32 %i.0, %n ; <i1> [#uses=1]
+ br i1 %cmp, label %for.body, label %for.cond.for.end_crit_edge
for.cond.for.end_crit_edge: ; preds = %for.cond
- br label %for.end
+ br label %for.end
-; CHECK: for.body:
-; CHECK-NEXT: %tmp3 = load i32, ptr @p
for.body: ; preds = %for.cond
- %tmp3 = load i32, ptr @p ; <i32> [#uses=1]
- %dec = add i32 %tmp3, -1 ; <i32> [#uses=2]
- store i32 %dec, ptr @p
- %cmp6 = icmp slt i32 %dec, 0 ; <i1> [#uses=1]
- br i1 %cmp6, label %for.body.for.end_crit_edge, label %for.inc
+ %tmp3 = load i32, ptr @p ; <i32> [#uses=1]
+ %dec = add i32 %tmp3, -1 ; <i32> [#uses=2]
+ store i32 %dec, ptr @p
+ %cmp6 = icmp slt i32 %dec, 0 ; <i1> [#uses=1]
+ br i1 %cmp6, label %for.body.for.end_crit_edge, label %for.inc
-; CHECK: for.body.for.end_crit_edge:
for.body.for.end_crit_edge: ; preds = %for.body
- br label %for.end
+ br label %for.end
for.inc: ; preds = %for.body
- %indvar.next = add i32 %i.0, 1 ; <i32> [#uses=1]
- br label %for.cond
+ %indvar.next = add i32 %i.0, 1 ; <i32> [#uses=1]
+ br label %for.cond
for.end: ; preds = %for.body.for.end_crit_edge, %for.cond.for.end_crit_edge
- %tmp9 = load i32, ptr @p ; <i32> [#uses=1]
- ret i32 %tmp9
+ %tmp9 = load i32, ptr @p ; <i32> [#uses=1]
+ ret i32 %tmp9
}
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
diff --git a/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll b/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
index 3df63beefea68..abbb17f11f436 100644
--- a/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
+++ b/llvm/test/Transforms/GVN/PRE/preserve-tbaa.ll
@@ -1,13 +1,45 @@
-; RUN: opt -passes=gvn -S < %s | FileCheck %s
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -passes=gvn -S < %s | FileCheck %s --check-prefixes=CHECK,MDEP
+; RUN: opt -passes='gvn<memoryssa>' -S < %s | FileCheck %s --check-prefixes=CHECK,MSSA
target datalayout = "e-p:64:64:64"
; GVN should preserve the TBAA tag on loads when doing PRE.
-; CHECK-LABEL: @test(
-; CHECK: %tmp33.pre = load i16, ptr %P, align 2, !tbaa !0
-; CHECK: br label %for.body
define void @test(ptr %P, ptr %Q, i1 %arg) nounwind {
+; MDEP-LABEL: define void @test(
+; MDEP-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
+; MDEP-NEXT: [[ENTRY:.*:]]
+; MDEP-NEXT: br i1 [[ARG]], label %[[BB_NPH:.*]], label %[[FOR_END:.*]]
+; MDEP: [[BB_NPH]]:
+; MDEP-NEXT: [[TMP33_PRE:%.*]] = load i16, ptr [[P]], align 2, !tbaa [[TBAA0:![0-9]+]]
+; MDEP-NEXT: br label %[[FOR_BODY:.*]]
+; MDEP: [[FOR_BODY]]:
+; MDEP-NEXT: [[TMP33:%.*]] = phi i16 [ 0, %[[FOR_BODY]] ], [ [[TMP33_PRE]], %[[BB_NPH]] ]
+; MDEP-NEXT: store i16 [[TMP33]], ptr [[Q]], align 2
+; MDEP-NEXT: store i16 0, ptr [[P]], align 2, !tbaa [[TBAA0]]
+; MDEP-NEXT: br i1 false, label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_BODY]]
+; MDEP: [[FOR_BODY_FOR_END_CRIT_EDGE]]:
+; MDEP-NEXT: br label %[[FOR_END]]
+; MDEP: [[FOR_END]]:
+; MDEP-NEXT: ret void
+;
+; MSSA-LABEL: define void @test(
+; MSSA-SAME: ptr [[P:%.*]], ptr [[Q:%.*]], i1 [[ARG:%.*]]) #[[ATTR0:[0-9]+]] {
+; MSSA-NEXT: [[ENTRY:.*:]]
+; MSSA-NEXT: br i1 [[ARG]], label %[[BB_NPH:.*]], label %[[FOR_END:.*]]
+; MSSA: [[BB_NPH]]:
+; MSSA-NEXT: br label %[[FOR_BODY:.*]]
+; MSSA: [[FOR_BODY]]:
+; MSSA-NEXT: [[TMP33:%.*]] = load i16, ptr [[P]], align 2, !tbaa [[TBAA0:![0-9]+]]
+; MSSA-NEXT: store i16 [[TMP33]], ptr [[Q]], align 2
+; MSSA-NEXT: store i16 0, ptr [[P]], align 2, !tbaa [[TBAA0]]
+; MSSA-NEXT: br i1 false, label %[[FOR_BODY_FOR_END_CRIT_EDGE:.*]], label %[[FOR_BODY]]
+; MSSA: [[FOR_BODY_FOR_END_CRIT_EDGE]]:
+; MSSA-NEXT: br label %[[FOR_END]]
+; MSSA: [[FOR_END]]:
+; MSSA-NEXT: ret void
+;
entry:
br i1 %arg, label %bb.nph, label %for.end
@@ -29,3 +61,16 @@ for.end: ; preds = %for.body, %entry
!1 = !{!"omnipotent char", !2}
!2 = !{!"Simple C/C++ TBAA"}
!3 = !{!"short", !1}
+;.
+; MDEP: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
+; MDEP: [[META1]] = !{!"short", [[META2:![0-9]+]]}
+; MDEP: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]]}
+; MDEP: [[META3]] = !{!"Simple C/C++ TBAA"}
+;.
+; MSSA: [[TBAA0]] = !{[[META1:![0-9]+]], [[META1]], i64 0}
+; MSSA: [[META1]] = !{!"short", [[META2:![0-9]+]]}
+; MSSA: [[META2]] = !{!"omnipotent char", [[META3:![0-9]+]]}
+; MSSA: [[META3]] = !{!"Simple C/C++ TBAA"}
+;.
+;; NOTE: These prefixes are unused and the list is autogenerated. Do not add tests below this line:
+; CHECK: {{.*}}
More information about the llvm-commits
mailing list