[llvm] 13b4d1b - [SimplifyCFG][LICM] Add additional speculation tests
Nikita Popov via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 18 05:49:08 PDT 2024
Author: Nikita Popov
Date: 2024-09-18T14:48:58+02:00
New Revision: 13b4d1bfeacc441d792557b42759f258dc4316e6
URL: https://github.com/llvm/llvm-project/commit/13b4d1bfeacc441d792557b42759f258dc4316e6
DIFF: https://github.com/llvm/llvm-project/commit/13b4d1bfeacc441d792557b42759f258dc4316e6.diff
LOG: [SimplifyCFG][LICM] Add additional speculation tests
These are related to https://github.com/llvm/llvm-project/issues/108854.
Added:
llvm/test/Transforms/SimplifyCFG/speculate-derefable-load.ll
Modified:
llvm/test/Transforms/LICM/hoist-deref-load.ll
Removed:
################################################################################
diff --git a/llvm/test/Transforms/LICM/hoist-deref-load.ll b/llvm/test/Transforms/LICM/hoist-deref-load.ll
index 149976ab18746b..c498e85ddd6c29 100644
--- a/llvm/test/Transforms/LICM/hoist-deref-load.ll
+++ b/llvm/test/Transforms/LICM/hoist-deref-load.ll
@@ -420,7 +420,7 @@ for.end: ; preds = %for.inc, %entry
define void @test7(ptr noalias %a, ptr %b, ptr %cptr, i32 %n) #0 {
; CHECK-LABEL: @test7(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable !0, !align !0
+; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable [[META0:![0-9]+]], !align [[META0]]
; CHECK-NEXT: [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body.preheader:
@@ -492,7 +492,7 @@ for.end: ; preds = %for.inc, %entry
define void @test8(ptr noalias %a, ptr %b, ptr %cptr, i32 %n) #0 {
; CHECK-LABEL: @test8(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable_or_null !0, !align !0
+; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable_or_null [[META0]], !align [[META0]]
; CHECK-NEXT: [[NOT_NULL:%.*]] = icmp ne ptr [[C]], null
; CHECK-NEXT: br i1 [[NOT_NULL]], label [[NOT_NULL:%.*]], label [[FOR_END:%.*]]
; CHECK: not.null:
@@ -562,7 +562,7 @@ for.end: ; preds = %for.inc, %entry, %n
define void @test9(ptr noalias %a, ptr %b, ptr %cptr, i32 %n) #0 {
; CHECK-LABEL: @test9(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable_or_null !0
+; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable_or_null [[META0]]
; CHECK-NEXT: [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body.preheader:
@@ -693,7 +693,7 @@ define void @test11(ptr noalias %a, ptr %b, ptr dereferenceable(8) %cptr, i32 %n
; CHECK-NEXT: [[CMP11:%.*]] = icmp sgt i32 [[N:%.*]], 0
; CHECK-NEXT: br i1 [[CMP11]], label [[FOR_BODY_PREHEADER:%.*]], label [[FOR_END:%.*]]
; CHECK: for.body.preheader:
-; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable !0
+; CHECK-NEXT: [[C:%.*]] = load ptr, ptr [[CPTR:%.*]], align 8, !dereferenceable [[META0]]
; CHECK-NEXT: br label [[FOR_BODY:%.*]]
; CHECK: for.body:
; CHECK-NEXT: [[INDVARS_IV:%.*]] = phi i64 [ [[INDVARS_IV_NEXT:%.*]], [[FOR_INC:%.*]] ], [ 0, [[FOR_BODY_PREHEADER]] ]
@@ -1164,5 +1164,78 @@ for.end: ; preds = %for.inc, %entry
ret void
}
+declare void @use(i64)
+
+define void @licm_deref_no_hoist(i1 %c1, i1 %c2, ptr align 8 dereferenceable(8) %p1) {
+; CHECK-LABEL: @licm_deref_no_hoist(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P1:%.*]], align 8, !align [[META1:![0-9]+]]
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]
+; CHECK: if:
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P2]], align 8
+; CHECK-NEXT: call void @use(i64 [[V]]) #[[ATTR1:[0-9]+]]
+; CHECK-NEXT: br label [[LOOP_LATCH]]
+; CHECK: loop.latch:
+; CHECK-NEXT: br i1 [[C2:%.*]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ br label %loop
+
+loop:
+ br i1 %c1, label %if, label %loop.latch
+
+if:
+ %p2 = load ptr, ptr %p1, align 8, !dereferenceable !1, !align !1
+ %v = load i64, ptr %p2, align 8
+ call void @use(i64 %v) memory(none)
+ br label %loop.latch
+
+loop.latch:
+ br i1 %c2, label %loop, label %exit
+
+exit:
+ ret void
+}
+
+define void @licm_deref_hoist(i1 %c1, i1 %c2, ptr align 8 dereferenceable(8) %p1) {
+; CHECK-LABEL: @licm_deref_hoist(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P1:%.*]], align 8, !dereferenceable [[META1]], !align [[META1]]
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P2]], align 8
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: br i1 [[C1:%.*]], label [[IF:%.*]], label [[LOOP_LATCH:%.*]]
+; CHECK: if:
+; CHECK-NEXT: call void @use(i64 [[V]]) #[[ATTR1]]
+; CHECK-NEXT: br label [[LOOP_LATCH]]
+; CHECK: loop.latch:
+; CHECK-NEXT: br i1 [[C2:%.*]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ %p2 = load ptr, ptr %p1, align 8, !dereferenceable !1, !align !1
+ br label %loop
+
+loop:
+ br i1 %c1, label %if, label %loop.latch
+
+if:
+ %v = load i64, ptr %p2, align 8
+ call void @use(i64 %v) memory(none)
+ br label %loop.latch
+
+loop.latch:
+ br i1 %c2, label %loop, label %exit
+
+exit:
+ ret void
+}
+
attributes #0 = { nounwind uwtable nofree nosync }
!0 = !{i64 4}
+!1 = !{i64 8}
diff --git a/llvm/test/Transforms/SimplifyCFG/speculate-derefable-load.ll b/llvm/test/Transforms/SimplifyCFG/speculate-derefable-load.ll
new file mode 100644
index 00000000000000..9e3f333018e680
--- /dev/null
+++ b/llvm/test/Transforms/SimplifyCFG/speculate-derefable-load.ll
@@ -0,0 +1,198 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5
+; RUN: opt -S -passes=simplifycfg < %s | FileCheck %s
+
+define i64 @align_deref_align(i1 %c, ptr %p) {
+; CHECK-LABEL: define i64 @align_deref_align(
+; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 8), "align"(ptr [[P]], i64 8) ]
+; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[EXIT:.*]]
+; CHECK: [[IF]]:
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P]], align 8
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[V]], %[[IF]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 8), "align"(ptr %p, i64 8) ]
+ br i1 %c, label %if, label %exit
+
+if:
+ %v = load i64, ptr %p, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if ], [ 0, %entry ]
+ ret i64 %res
+}
+
+define i64 @assume_deref_align2(i1 %c1, i32 %x, ptr %p) {
+; CHECK-LABEL: define i64 @assume_deref_align2(
+; CHECK-SAME: i1 [[C1:%.*]], i32 [[X:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 8), "align"(ptr [[P]], i64 8) ]
+; CHECK-NEXT: br i1 [[C1]], label %[[IF1:.*]], label %[[EXIT:.*]]
+; CHECK: [[IF1]]:
+; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT: br i1 [[C2]], label %[[IF2:.*]], label %[[EXIT]]
+; CHECK: [[IF2]]:
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P]], align 8
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[V]], %[[IF2]] ], [ 1, %[[IF1]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 8), "align"(ptr %p, i64 8) ]
+ br i1 %c1, label %if1, label %exit
+
+if1:
+ %c2 = icmp ugt i32 %x, 10
+ br i1 %c2, label %if2, label %exit
+
+if2:
+ %v = load i64, ptr %p, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if2 ], [ 1, %if1 ], [ 0, %entry ]
+ ret i64 %res
+}
+
+define i64 @assume_deref_align_not_dominating(i1 %c, ptr %p) {
+; CHECK-LABEL: define i64 @assume_deref_align_not_dominating(
+; CHECK-SAME: i1 [[C:%.*]], ptr [[P:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br i1 [[C]], label %[[IF:.*]], label %[[EXIT:.*]]
+; CHECK: [[IF]]:
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P]], align 8
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[V]], %[[IF]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: call void @llvm.assume(i1 true) [ "dereferenceable"(ptr [[P]], i64 8), "align"(ptr [[P]], i64 8) ]
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ br i1 %c, label %if, label %exit
+
+if:
+ %v = load i64, ptr %p, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if ], [ 0, %entry ]
+ call void @llvm.assume(i1 true) [ "dereferenceable"(ptr %p, i64 8), "align"(ptr %p, i64 8) ]
+ ret i64 %res
+}
+
+; FIXME: This is a miscompile.
+define i64 @deref_no_hoist(i1 %c, ptr align 8 dereferenceable(8) %p1) {
+; CHECK-LABEL: define i64 @deref_no_hoist(
+; CHECK-SAME: i1 [[C:%.*]], ptr align 8 dereferenceable(8) [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P1]], align 8, !align [[META0:![0-9]+]]
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P2]], align 8
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i64 [[V]], i64 0
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ br i1 %c, label %if, label %exit
+
+if:
+ %p2 = load ptr, ptr %p1, align 8, !dereferenceable !0, !align !0
+ %v = load i64, ptr %p2, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if ], [ 0, %entry ]
+ ret i64 %res
+}
+
+define i64 @deref_hoist(i1 %c, ptr align 8 dereferenceable(8) %p1) {
+; CHECK-LABEL: define i64 @deref_hoist(
+; CHECK-SAME: i1 [[C:%.*]], ptr align 8 dereferenceable(8) [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P1]], align 8, !dereferenceable [[META0]], !align [[META0]]
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P2]], align 8
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[C]], i64 [[V]], i64 0
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ %p2 = load ptr, ptr %p1, align 8, !dereferenceable !0, !align !0
+ br i1 %c, label %if, label %exit
+
+if:
+ %v = load i64, ptr %p2, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if ], [ 0, %entry ]
+ ret i64 %res
+}
+
+define i64 @deref_no_hoist2(i1 %c1, i32 %x, ptr align 8 dereferenceable(8) %p1) {
+; CHECK-LABEL: define i64 @deref_no_hoist2(
+; CHECK-SAME: i1 [[C1:%.*]], i32 [[X:%.*]], ptr align 8 dereferenceable(8) [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*]]:
+; CHECK-NEXT: br i1 [[C1]], label %[[IF1:.*]], label %[[EXIT:.*]]
+; CHECK: [[IF1]]:
+; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT: br i1 [[C2]], label %[[IF2:.*]], label %[[EXIT]]
+; CHECK: [[IF2]]:
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P1]], align 8, !dereferenceable [[META0]], !align [[META0]]
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P2]], align 8
+; CHECK-NEXT: br label %[[EXIT]]
+; CHECK: [[EXIT]]:
+; CHECK-NEXT: [[RES:%.*]] = phi i64 [ [[V]], %[[IF2]] ], [ 1, %[[IF1]] ], [ 0, %[[ENTRY]] ]
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ br i1 %c1, label %if1, label %exit
+
+if1:
+ %c2 = icmp ugt i32 %x, 10
+ br i1 %c2, label %if2, label %exit
+
+if2:
+ %p2 = load ptr, ptr %p1, align 8, !dereferenceable !0, !align !0
+ %v = load i64, ptr %p2, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if2 ], [ 1, %if1 ], [ 0, %entry ]
+ ret i64 %res
+}
+
+define i64 @deref_hoist2(i1 %c1, i32 %x, ptr align 8 dereferenceable(8) %p1) {
+; CHECK-LABEL: define i64 @deref_hoist2(
+; CHECK-SAME: i1 [[C1:%.*]], i32 [[X:%.*]], ptr align 8 dereferenceable(8) [[P1:%.*]]) {
+; CHECK-NEXT: [[ENTRY:.*:]]
+; CHECK-NEXT: [[P2:%.*]] = load ptr, ptr [[P1]], align 8, !dereferenceable [[META0]], !align [[META0]]
+; CHECK-NEXT: [[C2:%.*]] = icmp ugt i32 [[X]], 10
+; CHECK-NEXT: [[V:%.*]] = load i64, ptr [[P2]], align 8
+; CHECK-NEXT: [[SPEC_SELECT:%.*]] = select i1 [[C2]], i64 [[V]], i64 1
+; CHECK-NEXT: [[RES:%.*]] = select i1 [[C1]], i64 [[SPEC_SELECT]], i64 0
+; CHECK-NEXT: ret i64 [[RES]]
+;
+entry:
+ %p2 = load ptr, ptr %p1, align 8, !dereferenceable !0, !align !0
+ br i1 %c1, label %if1, label %exit
+
+if1:
+ %c2 = icmp ugt i32 %x, 10
+ br i1 %c2, label %if2, label %exit
+
+if2:
+ %v = load i64, ptr %p2, align 8
+ br label %exit
+
+exit:
+ %res = phi i64 [ %v, %if2 ], [ 1, %if1 ], [ 0, %entry ]
+ ret i64 %res
+}
+
+!0 = !{i64 8}
+;.
+; CHECK: [[META0]] = !{i64 8}
+;.
More information about the llvm-commits
mailing list