[OpenMPOpt][FIX] Avoid removing barriers in callees
authorJohannes Doerfert <johannes@jdoerfert.de>
Mon, 20 Mar 2023 23:01:39 +0000 (16:01 -0700)
committerJohannes Doerfert <johannes@jdoerfert.de>
Tue, 21 Mar 2023 00:44:24 +0000 (17:44 -0700)
We could be smarter about this, e.g., if the callee has a single call
site, but for now we first avoid the miscompile.

llvm/lib/Transforms/IPO/OpenMPOpt.cpp
llvm/test/Transforms/OpenMP/barrier_removal.ll

index a25537e..3c91508 100644 (file)
@@ -2619,6 +2619,8 @@ struct AAExecutionDomainFunction : public AAExecutionDomain {
           CallBase *LastCB = Worklist.pop_back_val();
           if (!Visited.insert(LastCB))
             continue;
+          if (LastCB->getFunction() != getAnchorScope())
+            continue;
           if (!DeletedBarriers.count(LastCB)) {
             A.deleteAfterManifest(*LastCB);
             continue;
index edc0273..77be52e 100644 (file)
@@ -632,16 +632,11 @@ m:
 }
 
 define internal void @write_then_barrier0(i32* %p) {
-; MODULE-LABEL: define {{[^@]+}}@write_then_barrier0
-; MODULE-SAME: (ptr [[P:%.*]]) {
-; MODULE-NEXT:    store i32 0, ptr [[P]], align 4
-; MODULE-NEXT:    ret void
-;
-; CGSCC-LABEL: define {{[^@]+}}@write_then_barrier0
-; CGSCC-SAME: (ptr [[P:%.*]]) {
-; CGSCC-NEXT:    store i32 0, ptr [[P]], align 4
-; CGSCC-NEXT:    call void @aligned_barrier()
-; CGSCC-NEXT:    ret void
+; CHECK-LABEL: define {{[^@]+}}@write_then_barrier0
+; CHECK-SAME: (ptr [[P:%.*]]) {
+; CHECK-NEXT:    store i32 0, ptr [[P]], align 4
+; CHECK-NEXT:    call void @aligned_barrier()
+; CHECK-NEXT:    ret void
 ;
   store i32 0, i32* %p
   call void @aligned_barrier()
@@ -980,8 +975,40 @@ m3:
   ret void
 }
 
+; Verify we do not remove the barrier in the callee.
+define internal void @callee_barrier() {
+; CHECK-LABEL: define {{[^@]+}}@callee_barrier() {
+; CHECK-NEXT:    call void @aligned_barrier()
+; CHECK-NEXT:    ret void
+;
+  call void @aligned_barrier()
+  ret void
+}
+define void @caller_barrier1() {
+; CHECK-LABEL: define {{[^@]+}}@caller_barrier1() {
+; CHECK-NEXT:    call void @callee_barrier()
+; CHECK-NEXT:    ret void
+;
+  call void @aligned_barrier()
+  call void @callee_barrier()
+  call void @aligned_barrier()
+  ret void
+}
+define void @caller_barrier2() {
+; CHECK-LABEL: define {{[^@]+}}@caller_barrier2() {
+; CHECK-NEXT:    call void @unknown()
+; CHECK-NEXT:    call void @callee_barrier()
+; CHECK-NEXT:    call void @unknown()
+; CHECK-NEXT:    ret void
+;
+  call void @unknown()
+  call void @callee_barrier()
+  call void @unknown()
+  ret void
+}
+
 !llvm.module.flags = !{!16,!15}
-!nvvm.annotations = !{!0,!1,!2,!3,!4,!5,!6,!7,!8,!9,!10,!11,!12,!13,!14,!17,!18,!19,!20,!21,!22,!23}
+!nvvm.annotations = !{!0,!1,!2,!3,!4,!5,!6,!7,!8,!9,!10,!11,!12,!13,!14,!17,!18,!19,!20,!21,!22,!23,!24,!25}
 
 !0 = !{void ()* @pos_empty_1, !"kernel", i32 1}
 !1 = !{void ()* @pos_empty_2, !"kernel", i32 1}
@@ -992,6 +1019,8 @@ m3:
 !17 = !{void ()* @pos_empty_7a, !"kernel", i32 1}
 !18 = !{void ()* @pos_empty_7b, !"kernel", i32 1}
 !23 = !{void (i1)* @pos_empty_8, !"kernel", i32 1}
+!24 = !{void ()* @caller_barrier1, !"kernel", i32 1}
+!25 = !{void ()* @caller_barrier2, !"kernel", i32 1}
 !6 = !{void ()* @neg_empty_8, !"kernel", i32 1}
 !19 = !{void (i1)* @neg_empty_9, !"kernel", i32 1}
 !20 = !{void ()* @pos_empty_10, !"kernel", i32 1}
@@ -1038,4 +1067,6 @@ m3:
 ; CHECK: [[META21:![0-9]+]] = !{ptr @pos_empty_11, !"kernel", i32 1}
 ; CHECK: [[META22:![0-9]+]] = !{ptr @neg_empty_12, !"kernel", i32 1}
 ; CHECK: [[META23:![0-9]+]] = !{ptr @pos_empty_8, !"kernel", i32 1}
+; CHECK: [[META24:![0-9]+]] = !{ptr @caller_barrier1, !"kernel", i32 1}
+; CHECK: [[META25:![0-9]+]] = !{ptr @caller_barrier2, !"kernel", i32 1}
 ;.