[llvm] 40b0ab2 - [SimplifyCFG] Pre-commit test for extending HoistThenElseCodeToIf.

via llvm-commits llvm-commits at lists.llvm.org
Tue Sep 19 16:22:26 PDT 2023


Author: DianQK
Date: 2023-09-20T07:21:48+08:00
New Revision: 40b0ab287f9f5c58fa35a9a97cc49f104bef45ed

URL: https://github.com/llvm/llvm-project/commit/40b0ab287f9f5c58fa35a9a97cc49f104bef45ed
DIFF: https://github.com/llvm/llvm-project/commit/40b0ab287f9f5c58fa35a9a97cc49f104bef45ed.diff

LOG: [SimplifyCFG] Pre-commit test for extending HoistThenElseCodeToIf.

Pre-commit test for D155711.

Differential Revision: https://reviews.llvm.org/D156617

Added: 
    llvm/test/Transforms/SimplifyCFG/hoist-common-code-with-unreachable.ll

Modified: 
    llvm/test/Transforms/SimplifyCFG/HoistCode.ll
    llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
    llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll

Removed: 
    


################################################################################
diff  --git a/llvm/test/Transforms/SimplifyCFG/HoistCode.ll b/llvm/test/Transforms/SimplifyCFG/HoistCode.ll
index 10c6f81c91ac599..0b634fac8c640ae 100644
--- a/llvm/test/Transforms/SimplifyCFG/HoistCode.ll
+++ b/llvm/test/Transforms/SimplifyCFG/HoistCode.ll
@@ -17,6 +17,39 @@ F:              ; preds = %0
   ret void
 }
 
+define void @foo_switch(i64 %C, ptr %P) {
+; CHECK-LABEL: @foo_switch(
+; CHECK-NEXT:    switch i64 [[C:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       common.ret:
+; CHECK-NEXT:    ret void
+; CHECK:       bb0:
+; CHECK-NEXT:    store i32 7, ptr [[P:%.*]], align 4
+; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 7, ptr [[P]], align 4
+; CHECK-NEXT:    br label [[COMMON_RET]]
+; CHECK:       bb2:
+; CHECK-NEXT:    store i32 7, ptr [[P]], align 4
+; CHECK-NEXT:    br label [[COMMON_RET]]
+;
+  switch i64 %C, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:              ; preds = %0
+  store i32 7, ptr %P
+  ret void
+bb1:              ; preds = %0
+  store i32 7, ptr %P
+  ret void
+bb2:              ; preds = %0
+  store i32 7, ptr %P
+  ret void
+}
+
 define float @PR39535min(float %x) {
 ; CHECK-LABEL: @PR39535min(
 ; CHECK-NEXT:  entry:
@@ -38,3 +71,38 @@ cond.end:
   %cond = phi fast float [ 0.0, %cond.true ], [ %x, %cond.false ]
   ret float %cond
 }
+
+define float @PR39535min_switch(i64 %i, float %x) {
+; CHECK-LABEL: @PR39535min_switch(
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[END:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb1:
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       bb2:
+; CHECK-NEXT:    br label [[END]]
+; CHECK:       end:
+; CHECK-NEXT:    [[COND:%.*]] = phi fast float [ [[X:%.*]], [[BB1]] ], [ [[X]], [[BB2]] ], [ 0.000000e+00, [[ENTRY:%.*]] ]
+; CHECK-NEXT:    ret float [[COND]]
+;
+entry:
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+
+bb0:
+  br label %end
+
+bb1:
+  br label %end
+
+bb2:
+  br label %end
+
+end:
+  %cond = phi fast float [ 0.0, %bb0 ], [ %x, %bb1 ], [ %x, %bb2 ]
+  ret float %cond
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/hoist-common-code-with-unreachable.ll b/llvm/test/Transforms/SimplifyCFG/hoist-common-code-with-unreachable.ll
new file mode 100644
index 000000000000000..8cb6339713d6f6a
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-common-code-with-unreachable.ll
@@ -0,0 +1,99 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt < %s -passes='simplifycfg<hoist-common-insts;no-sink-common-insts>' -simplifycfg-require-and-preserve-domtree=1 -S | FileCheck %s
+
+define i1 @common_instr_with_unreachable(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: @common_instr_with_unreachable(
+; CHECK-NEXT:  start:
+; CHECK-NEXT:    switch i64 [[A:%.*]], label [[UNREACHABLE:%.*]] [
+; CHECK-NEXT:    i64 0, label [[BB0:%.*]]
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       unreachable:
+; CHECK-NEXT:    unreachable
+; CHECK:       bb0:
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  switch i64 %a, label %unreachable [
+  i64 0, label %bb0
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+
+unreachable:
+  unreachable
+
+bb0:                                              ; preds = %start
+  %0 = icmp eq i64 %b, %c
+  br label %exit
+
+bb1:                                              ; preds = %start
+  %1 = icmp eq i64 %b, %c
+  br label %exit
+
+bb2:                                              ; preds = %start
+  %2 = icmp eq i64 %b, %c
+  br label %exit
+
+exit:                                             ; preds = %bb2, %bb1, %bb0
+  %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
+  ret i1 %result
+}
+
+define i1 @common_instr_with_unreachable_2(i64 %a, i64 %b, i64 %c) {
+; CHECK-LABEL: @common_instr_with_unreachable_2(
+; CHECK-NEXT:  start:
+; CHECK-NEXT:    switch i64 [[A:%.*]], label [[BB1:%.*]] [
+; CHECK-NEXT:    i64 0, label [[BB0:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  switch i64 %a, label %bb1 [
+  i64 0, label %bb0
+  i64 1, label %unreachable
+  i64 2, label %bb2
+  ]
+
+unreachable:
+  unreachable
+
+bb0:                                              ; preds = %start
+  %0 = icmp eq i64 %b, %c
+  br label %exit
+
+bb1:                                              ; preds = %start
+  %1 = icmp eq i64 %b, %c
+  br label %exit
+
+bb2:                                              ; preds = %start
+  %2 = icmp eq i64 %b, %c
+  br label %exit
+
+exit:                                             ; preds = %bb2, %bb1, %bb0
+  %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
+  ret i1 %result
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll b/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
index 556e1b9ca066228..43fb8faad7cfd94 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-common-code.ll
@@ -24,3 +24,133 @@ F:              ; preds = %0
   ret void
 }
 
+define void @test_switch(i64 %i, ptr %Q) {
+; CHECK-LABEL: @test_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       common.ret:
+; CHECK-NEXT:    ret void
+; CHECK:       bb0:
+; CHECK-NEXT:    store i32 1, ptr [[Q:%.*]], align 4
+; CHECK-NEXT:    [[A:%.*]] = load i32, ptr [[Q]], align 4
+; CHECK-NEXT:    call void @bar(i32 [[A]])
+; CHECK-NEXT:    br label [[COMMON_RET:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    store i32 1, ptr [[Q]], align 4
+; CHECK-NEXT:    [[B:%.*]] = load i32, ptr [[Q]], align 4
+; CHECK-NEXT:    call void @bar(i32 [[B]])
+; CHECK-NEXT:    br label [[COMMON_RET]]
+; CHECK:       bb2:
+; CHECK-NEXT:    store i32 1, ptr [[Q]], align 4
+; CHECK-NEXT:    [[C:%.*]] = load i32, ptr [[Q]], align 4
+; CHECK-NEXT:    call void @bar(i32 [[C]])
+; CHECK-NEXT:    br label [[COMMON_RET]]
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:              ; preds = %0
+  store i32 1, ptr %Q
+  %A = load i32, ptr %Q               ; <i32> [#uses=1]
+  call void @bar( i32 %A )
+  ret void
+bb1:              ; preds = %0
+  store i32 1, ptr %Q
+  %B = load i32, ptr %Q               ; <i32> [#uses=1]
+  call void @bar( i32 %B )
+  ret void
+bb2:              ; preds = %0
+  store i32 1, ptr %Q
+  %C = load i32, ptr %Q               ; <i32> [#uses=1]
+  call void @bar( i32 %C )
+  ret void
+}
+
+define i1 @common_instr_on_switch(i64 %a, i64 %b, i64 %c) unnamed_addr {
+; CHECK-LABEL: @common_instr_on_switch(
+; CHECK-NEXT:  start:
+; CHECK-NEXT:    switch i64 [[A:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  switch i64 %a, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+
+bb0:                                              ; preds = %start
+  %0 = icmp eq i64 %b, %c
+  br label %exit
+
+bb1:                                              ; preds = %start
+  %1 = icmp eq i64 %b, %c
+  br label %exit
+
+bb2:                                              ; preds = %start
+  %2 = icmp eq i64 %b, %c
+  br label %exit
+
+exit:                                             ; preds = %bb2, %bb1, %bb0
+  %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
+  ret i1 %result
+}
+
+define i1 @partial_common_instr_on_switch(i64 %a, i64 %b, i64 %c) unnamed_addr {
+; CHECK-LABEL: @partial_common_instr_on_switch(
+; CHECK-NEXT:  start:
+; CHECK-NEXT:    switch i64 [[A:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[TMP0:%.*]] = icmp eq i64 [[B:%.*]], [[C:%.*]]
+; CHECK-NEXT:    br label [[EXIT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[TMP1:%.*]] = icmp ne i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[TMP2:%.*]] = icmp eq i64 [[B]], [[C]]
+; CHECK-NEXT:    br label [[EXIT]]
+; CHECK:       exit:
+; CHECK-NEXT:    [[RESULT:%.*]] = phi i1 [ [[TMP0]], [[BB0]] ], [ [[TMP1]], [[BB1]] ], [ [[TMP2]], [[BB2]] ]
+; CHECK-NEXT:    ret i1 [[RESULT]]
+;
+start:
+  switch i64 %a, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+
+bb0:                                              ; preds = %start
+  %0 = icmp eq i64 %b, %c
+  br label %exit
+
+bb1:                                              ; preds = %start
+  %1 = icmp ne i64 %b, %c
+  br label %exit
+
+bb2:                                              ; preds = %start
+  %2 = icmp eq i64 %b, %c
+  br label %exit
+
+exit:                                             ; preds = %bb2, %bb1, %bb0
+  %result = phi i1 [ %0, %bb0 ], [ %1, %bb1 ], [ %2, %bb2 ]
+  ret i1 %result
+}

diff  --git a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
index b999b07fc24b4ce..b53224c944f1101 100644
--- a/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
+++ b/llvm/test/Transforms/SimplifyCFG/hoist-with-metadata.ll
@@ -19,10 +19,45 @@ out:
   ret void
 }
 
+define void @hoist_range_switch(i64 %i, ptr %p) {
+; CHECK-LABEL: @hoist_range_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !range [[RNG1:![0-9]+]]
+; CHECK-NEXT:    br label [[OUT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[E:%.*]] = load i8, ptr [[P]], align 1, !range [[RNG2:![0-9]+]]
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[F:%.*]] = load i8, ptr [[P]], align 1, !range [[RNG3:![0-9]+]]
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       out:
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = load i8, ptr %p, !range !0
+  br label %out
+bb1:
+  %e = load i8, ptr %p, !range !1
+  br label %out
+bb2:
+  %f = load i8, ptr %p, !range !3
+  br label %out
+out:
+  ret void
+}
+
 define void @hoist_both_noundef(i1 %c, ptr %p) {
 ; CHECK-LABEL: @hoist_both_noundef(
 ; CHECK-NEXT:  if:
-; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !1
+; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !4
 ; CHECK-NEXT:    ret void
 ;
 if:
@@ -40,6 +75,42 @@ out:
   ret void
 }
 
+
+define void @hoist_both_noundef_switch(i64 %i, ptr %p) {
+; CHECK-LABEL: @hoist_both_noundef_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !4
+; CHECK-NEXT:    br label [[OUT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[E:%.*]] = load i8, ptr [[P]], align 1, !noundef !4
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[F:%.*]] = load i8, ptr [[P]], align 1, !noundef !4
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       out:
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = load i8, ptr %p, !noundef !2
+  br label %out
+bb1:
+  %e = load i8, ptr %p, !noundef !2
+  br label %out
+bb2:
+  %f = load i8, ptr %p, !noundef !2
+  br label %out
+out:
+  ret void
+}
+
 define void @hoist_one_noundef(i1 %c, ptr %p) {
 ; CHECK-LABEL: @hoist_one_noundef(
 ; CHECK-NEXT:  if:
@@ -61,10 +132,45 @@ out:
   ret void
 }
 
+define void @hoist_one_noundef_switch(i64 %i, ptr %p) {
+; CHECK-LABEL: @hoist_one_noundef_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[T:%.*]] = load i8, ptr [[P:%.*]], align 1, !noundef !4
+; CHECK-NEXT:    br label [[OUT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[E:%.*]] = load i8, ptr [[P]], align 1
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[F:%.*]] = load i8, ptr [[P]], align 1, !noundef !4
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       out:
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = load i8, ptr %p, !noundef !2
+  br label %out
+bb1:
+  %e = load i8, ptr %p
+  br label %out
+bb2:
+  %f = load i8, ptr %p, !noundef !2
+  br label %out
+out:
+  ret void
+}
+
 define void @hoist_dereferenceable(i1 %c, ptr %p) {
 ; CHECK-LABEL: @hoist_dereferenceable(
 ; CHECK-NEXT:  if:
-; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !2
+; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !5
 ; CHECK-NEXT:    ret void
 ;
 if:
@@ -79,10 +185,45 @@ out:
   ret void
 }
 
+define void @hoist_dereferenceable_switch(i64 %i, ptr %p) {
+; CHECK-LABEL: @hoist_dereferenceable_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable !5
+; CHECK-NEXT:    br label [[OUT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[E:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !6
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[F:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable !7
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       out:
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = load ptr, ptr %p, !dereferenceable !{i64 10}
+  br label %out
+bb1:
+  %e = load ptr, ptr %p, !dereferenceable !{i64 20}
+  br label %out
+bb2:
+  %f = load ptr, ptr %p, !dereferenceable !{i64 30}
+  br label %out
+out:
+  ret void
+}
+
 define void @hoist_dereferenceable_or_null(i1 %c, ptr %p) {
 ; CHECK-LABEL: @hoist_dereferenceable_or_null(
 ; CHECK-NEXT:  if:
-; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null !2
+; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null !5
 ; CHECK-NEXT:    ret void
 ;
 if:
@@ -97,11 +238,46 @@ out:
   ret void
 }
 
+define void @hoist_dereferenceable_or_null_switch(i64 %i, ptr %p) {
+; CHECK-LABEL: @hoist_dereferenceable_or_null_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[T:%.*]] = load ptr, ptr [[P:%.*]], align 8, !dereferenceable_or_null !6
+; CHECK-NEXT:    br label [[OUT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[E:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable_or_null !5
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[F:%.*]] = load ptr, ptr [[P]], align 8, !dereferenceable_or_null !7
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       out:
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = load ptr, ptr %p, !dereferenceable_or_null !{i64 20}
+  br label %out
+bb1:
+  %e = load ptr, ptr %p, !dereferenceable_or_null !{i64 10}
+  br label %out
+bb2:
+  %f = load ptr, ptr %p, !dereferenceable_or_null !{i64 30}
+  br label %out
+out:
+  ret void
+}
+
 ; !range violation only returns poison, and is thus safe to speculate.
 define i32 @speculate_range(i1 %c, ptr dereferenceable(8) align 8 %p) {
 ; CHECK-LABEL: @speculate_range(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG3:![0-9]+]]
+; CHECK-NEXT:    [[V:%.*]] = load i32, ptr [[P:%.*]], align 4, !range [[RNG8:![0-9]+]]
 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], i32 [[V]], i32 0
 ; CHECK-NEXT:    ret i32 [[SPEC_SELECT]]
 ;
@@ -122,7 +298,7 @@ join:
 define ptr @speculate_nonnull(i1 %c, ptr dereferenceable(8) align 8 %p) {
 ; CHECK-LABEL: @speculate_nonnull(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull !1
+; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !nonnull !4
 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
 ; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
 ;
@@ -143,7 +319,7 @@ join:
 define ptr @speculate_align(i1 %c, ptr dereferenceable(8) align 8 %p) {
 ; CHECK-LABEL: @speculate_align(
 ; CHECK-NEXT:  entry:
-; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align !4
+; CHECK-NEXT:    [[V:%.*]] = load ptr, ptr [[P:%.*]], align 8, !align !9
 ; CHECK-NEXT:    [[SPEC_SELECT:%.*]] = select i1 [[C:%.*]], ptr [[V]], ptr null
 ; CHECK-NEXT:    ret ptr [[SPEC_SELECT]]
 ;
@@ -162,7 +338,7 @@ join:
 define void @hoist_fpmath(i1 %c, double %x) {
 ; CHECK-LABEL: @hoist_fpmath(
 ; CHECK-NEXT:  if:
-; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !5
+; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !10
 ; CHECK-NEXT:    ret void
 ;
 if:
@@ -177,14 +353,57 @@ out:
   ret void
 }
 
+define void @hoist_fpmath_switch(i64 %i, double %x) {
+; CHECK-LABEL: @hoist_fpmath_switch(
+; CHECK-NEXT:    switch i64 [[I:%.*]], label [[BB0:%.*]] [
+; CHECK-NEXT:    i64 1, label [[BB1:%.*]]
+; CHECK-NEXT:    i64 2, label [[BB2:%.*]]
+; CHECK-NEXT:    ]
+; CHECK:       bb0:
+; CHECK-NEXT:    [[T:%.*]] = fadd double [[X:%.*]], 1.000000e+00, !fpmath !10
+; CHECK-NEXT:    br label [[OUT:%.*]]
+; CHECK:       bb1:
+; CHECK-NEXT:    [[E:%.*]] = fadd double [[X]], 1.000000e+00, !fpmath !11
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       bb2:
+; CHECK-NEXT:    [[F:%.*]] = fadd double [[X]], 1.000000e+00, !fpmath !12
+; CHECK-NEXT:    br label [[OUT]]
+; CHECK:       out:
+; CHECK-NEXT:    ret void
+;
+  switch i64 %i, label %bb0 [
+  i64 1, label %bb1
+  i64 2, label %bb2
+  ]
+bb0:
+  %t = fadd double %x, 1.0, !fpmath !{ float 2.5 }
+  br label %out
+bb1:
+  %e = fadd double %x, 1.0, !fpmath !{ float 5.0 }
+  br label %out
+bb2:
+  %f = fadd double %x, 1.0, !fpmath !{ float 7.5 }
+  br label %out
+out:
+  ret void
+}
+
 !0 = !{ i8 0, i8 1 }
 !1 = !{ i8 3, i8 5 }
 !2 = !{}
+!3 = !{ i8 7, i8 9 }
 ;.
 ; CHECK: [[RNG0]] = !{i8 0, i8 1, i8 3, i8 5}
-; CHECK: [[META1:![0-9]+]] = !{}
-; CHECK: [[META2:![0-9]+]] = !{i64 10}
-; CHECK: [[RNG3]] = !{i32 0, i32 10}
-; CHECK: [[META4:![0-9]+]] = !{i64 4}
-; CHECK: [[META5:![0-9]+]] = !{float 2.500000e+00}
+; CHECK: [[RNG1]] = !{i8 0, i8 1}
+; CHECK: [[RNG2]] = !{i8 3, i8 5}
+; CHECK: [[RNG3]] = !{i8 7, i8 9}
+; CHECK: [[META4:![0-9]+]] = !{}
+; CHECK: [[META5:![0-9]+]] = !{i64 10}
+; CHECK: [[META6:![0-9]+]] = !{i64 20}
+; CHECK: [[META7:![0-9]+]] = !{i64 30}
+; CHECK: [[RNG8]] = !{i32 0, i32 10}
+; CHECK: [[META9:![0-9]+]] = !{i64 4}
+; CHECK: [[META10:![0-9]+]] = !{float 2.500000e+00}
+; CHECK: [[META11:![0-9]+]] = !{float 5.000000e+00}
+; CHECK: [[META12:![0-9]+]] = !{float 7.500000e+00}
 ;.


        


More information about the llvm-commits mailing list