-
Notifications
You must be signed in to change notification settings - Fork 15.2k
[DeadStoreElimination] Introduce test for #63473 (NFC) #98737
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[DeadStoreElimination] Introduce test for #63473 (NFC) #98737
Conversation
@llvm/pr-subscribers-llvm-transforms Author: Antonio Frighetto (antoniofrighetto) ChangesPreliminary tests addition. Full diff: https://github.com/llvm/llvm-project/pull/98737.diff 1 Files Affected:
diff --git a/llvm/test/Transforms/DeadStoreElimination/dependencies-cross-iterations.ll b/llvm/test/Transforms/DeadStoreElimination/dependencies-cross-iterations.ll
new file mode 100644
index 0000000000000..d446ebc6d2bd4
--- /dev/null
+++ b/llvm/test/Transforms/DeadStoreElimination/dependencies-cross-iterations.ll
@@ -0,0 +1,126 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
+; RUN: opt -passes=dse -S %s | FileCheck %s
+
+; No final read after clobbering.
+define void @test1(i64 %arg) #0 {
+; CHECK-LABEL: @test1(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i64], align 16
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [20 x i64], ptr [[ARRAY]], i64 0, i64 [[IV]]
+; CHECK-NEXT: store i64 0, ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[VAL]], [[ARG:%.*]]
+; CHECK-NEXT: store i64 [[ADD]], ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[IV]], 4
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: ret void
+;
+entry:
+ %array = alloca [20 x i64], align 16
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %ptr.1 = getelementptr inbounds [20 x i64], ptr %array, i64 0, i64 %iv
+ store i64 0, ptr %ptr.1, align 8
+ %val = load i64, ptr %ptr.1, align 8
+ %add = add nsw i64 %val, %arg
+ store i64 %add, ptr %ptr.1, align 8
+ %iv.next = add nuw nsw i64 %iv, 1
+ %cond = icmp ult i64 %iv, 4
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ ret void
+}
+
+; Unused final read of %ptr.1 after clobbering it.
+define void @test2(i64 %arg) #0 {
+; CHECK-LABEL: @test2(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i64], align 16
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [20 x i64], ptr [[ARRAY]], i64 0, i64 [[IV]]
+; CHECK-NEXT: store i64 0, ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[VAL]], [[ARG:%.*]]
+; CHECK-NEXT: store i64 [[ADD]], ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[IV]], 4
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: [[PTR_FIRST_ELEM:%.*]] = getelementptr inbounds [20 x i64], ptr [[ARRAY]], i64 0, i64 0
+; CHECK-NEXT: [[UNUSED_RV:%.*]] = load i64, ptr [[PTR_FIRST_ELEM]], align 8
+; CHECK-NEXT: ret void
+;
+entry:
+ %array = alloca [20 x i64], align 16
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %ptr.1 = getelementptr inbounds [20 x i64], ptr %array, i64 0, i64 %iv
+ store i64 0, ptr %ptr.1, align 8
+ %val = load i64, ptr %ptr.1, align 8
+ %add = add nsw i64 %val, %arg
+ store i64 %add, ptr %ptr.1, align 8
+ %iv.next = add nuw nsw i64 %iv, 1
+ %cond = icmp ult i64 %iv, 4
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ %ptr.first.elem = getelementptr inbounds [20 x i64], ptr %array, i64 0, i64 0
+ %unused_rv = load i64, ptr %ptr.first.elem, align 8
+ ret void
+}
+
+; Used final read after clobbering %ptr.1.
+define i64 @test3(i64 %arg) #0 {
+; CHECK-LABEL: @test3(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: [[ARRAY:%.*]] = alloca [20 x i64], align 16
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[IV:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[IV_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[PTR_1:%.*]] = getelementptr inbounds [20 x i64], ptr [[ARRAY]], i64 0, i64 [[IV]]
+; CHECK-NEXT: store i64 0, ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[VAL:%.*]] = load i64, ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[ADD:%.*]] = add nsw i64 [[VAL]], [[ARG:%.*]]
+; CHECK-NEXT: store i64 [[ADD]], ptr [[PTR_1]], align 8
+; CHECK-NEXT: [[IV_NEXT]] = add nuw nsw i64 [[IV]], 1
+; CHECK-NEXT: [[COND:%.*]] = icmp ult i64 [[IV]], 4
+; CHECK-NEXT: br i1 [[COND]], label [[LOOP]], label [[EXIT:%.*]]
+; CHECK: exit:
+; CHECK-NEXT: [[PTR_FIRST_ELEM:%.*]] = getelementptr inbounds [20 x i64], ptr [[ARRAY]], i64 0, i64 0
+; CHECK-NEXT: [[RV:%.*]] = load i64, ptr [[PTR_FIRST_ELEM]], align 8
+; CHECK-NEXT: ret i64 [[RV]]
+;
+entry:
+ %array = alloca [20 x i64], align 16
+ br label %loop
+
+loop: ; preds = %loop, %entry
+ %iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ]
+ %ptr.1 = getelementptr inbounds [20 x i64], ptr %array, i64 0, i64 %iv
+ store i64 0, ptr %ptr.1, align 8
+ %val = load i64, ptr %ptr.1, align 8
+ %add = add nsw i64 %val, %arg
+ store i64 %add, ptr %ptr.1, align 8
+ %iv.next = add nuw nsw i64 %iv, 1
+ %cond = icmp ult i64 %iv, 4
+ br i1 %cond, label %loop, label %exit
+
+exit: ; preds = %loop
+ %ptr.first.elem = getelementptr inbounds [20 x i64], ptr %array, i64 0, i64 0
+ %rv = load i64, ptr %ptr.first.elem, align 8
+ ret i64 %rv
+}
+
+attributes #0 = { mustprogress }
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would be good to also add a test case with cross-iteration dependencies in the loops?
|
||
loop: ; preds = %loop, %entry | ||
%iv = phi i64 [ 0, %entry ], [ %iv.next, %loop ] | ||
%ptr.iv = getelementptr inbounds [20 x i64], ptr %array, i64 0, i64 %iv |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can define this outside?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
test4
has been moved in read-clobber-after-overwrite.ll
. I'm not exactly sure how the test would benefit from defining this outside the loop. The idea is to show that the final load (MemoryUse(2)
) reads memory from the PN (2 = MemoryPhi({entry,liveOnEntry},{loop,1})
), and not directly from the store (1 = MemoryDef(2)
), to which it is still constrained though.
Reorganized the tests a bit, moved the read after clobbering out in |
Preliminary tests addition.