[llvm] c86a1e6 - [GVN] Do not combine convergent calls in GVN/NewGVN

Jay Foad via llvm-commits llvm-commits at lists.llvm.org
Fri May 19 13:29:34 PDT 2023


Author: Jay Foad
Date: 2023-05-19T21:27:35+01:00
New Revision: c86a1e6903e9935b808c1406f480c769279b69fa

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

LOG: [GVN] Do not combine convergent calls in GVN/NewGVN

Note that this is very conservative since it will not even combine
convergent calls that appear in the same basic block, but EarlyCSE will
handle that case.

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

Added: 
    

Modified: 
    llvm/lib/Transforms/Scalar/GVN.cpp
    llvm/lib/Transforms/Scalar/NewGVN.cpp
    llvm/test/Transforms/GVN/convergent.ll
    llvm/test/Transforms/NewGVN/convergent.ll

Removed: 
    


################################################################################
diff  --git a/llvm/lib/Transforms/Scalar/GVN.cpp b/llvm/lib/Transforms/Scalar/GVN.cpp
index 3e30f1582715..9350b251e5a6 100644
--- a/llvm/lib/Transforms/Scalar/GVN.cpp
+++ b/llvm/lib/Transforms/Scalar/GVN.cpp
@@ -473,6 +473,14 @@ uint32_t GVNPass::ValueTable::lookupOrAddCall(CallInst *C) {
     return nextValueNumber++;
   }
 
+  // Do not combine convergent calls since they implicitly depend on the set of
+  // threads that is currently executing, and they might be in 
diff erent basic
+  // blocks.
+  if (C->isConvergent()) {
+    valueNumbering[C] = nextValueNumber;
+    return nextValueNumber++;
+  }
+
   if (AA->doesNotAccessMemory(C)) {
     Expression exp = createExpr(C);
     uint32_t e = assignExpNewValueNum(exp).first;
@@ -2781,9 +2789,6 @@ bool GVNPass::performScalarPRE(Instruction *CurInst) {
     // We don't currently value number ANY inline asm calls.
     if (CallB->isInlineAsm())
       return false;
-    // Don't do PRE on convergent calls.
-    if (CallB->isConvergent())
-      return false;
   }
 
   uint32_t ValNo = VN.lookup(CurInst);

diff  --git a/llvm/lib/Transforms/Scalar/NewGVN.cpp b/llvm/lib/Transforms/Scalar/NewGVN.cpp
index 0647963e2d5a..3de55759ed3a 100644
--- a/llvm/lib/Transforms/Scalar/NewGVN.cpp
+++ b/llvm/lib/Transforms/Scalar/NewGVN.cpp
@@ -1613,6 +1613,12 @@ NewGVN::ExprResult NewGVN::performSymbolicCallEvaluation(Instruction *I) const {
   if (CI->getFunction()->isPresplitCoroutine())
     return ExprResult::none();
 
+  // Do not combine convergent calls since they implicitly depend on the set of
+  // threads that is currently executing, and they might be in 
diff erent basic
+  // blocks.
+  if (CI->isConvergent())
+    return ExprResult::none();
+
   if (AA->doesNotAccessMemory(CI)) {
     return ExprResult::some(
         createCallExpression(CI, TOPClass->getMemoryLeader()));

diff  --git a/llvm/test/Transforms/GVN/convergent.ll b/llvm/test/Transforms/GVN/convergent.ll
index e44e77c59f95..80781bc4927d 100644
--- a/llvm/test/Transforms/GVN/convergent.ll
+++ b/llvm/test/Transforms/GVN/convergent.ll
@@ -7,9 +7,11 @@ define i32 @foo(i1 %cond) {
 ; CHECK-NEXT:    [[V0:%.*]] = call i32 @llvm.convergent()
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BODY:%.*]], label [[END:%.*]]
 ; CHECK:       body:
+; CHECK-NEXT:    [[V1:%.*]] = call i32 @llvm.convergent()
 ; CHECK-NEXT:    br label [[END]]
 ; CHECK:       end:
-; CHECK-NEXT:    ret i32 [[V0]]
+; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[V0]], [[ENTRY:%.*]] ], [ [[V1]], [[BODY]] ]
+; CHECK-NEXT:    ret i32 [[RET]]
 ;
 entry:
   %v0 = call i32 @llvm.convergent()

diff  --git a/llvm/test/Transforms/NewGVN/convergent.ll b/llvm/test/Transforms/NewGVN/convergent.ll
index c087e86d6115..eceb071badcb 100644
--- a/llvm/test/Transforms/NewGVN/convergent.ll
+++ b/llvm/test/Transforms/NewGVN/convergent.ll
@@ -7,9 +7,11 @@ define i32 @foo(i1 %cond) {
 ; CHECK-NEXT:    [[V0:%.*]] = call i32 @llvm.convergent()
 ; CHECK-NEXT:    br i1 [[COND:%.*]], label [[BODY:%.*]], label [[END:%.*]]
 ; CHECK:       body:
+; CHECK-NEXT:    [[V1:%.*]] = call i32 @llvm.convergent()
 ; CHECK-NEXT:    br label [[END]]
 ; CHECK:       end:
-; CHECK-NEXT:    ret i32 [[V0]]
+; CHECK-NEXT:    [[RET:%.*]] = phi i32 [ [[V0]], [[ENTRY:%.*]] ], [ [[V1]], [[BODY]] ]
+; CHECK-NEXT:    ret i32 [[RET]]
 ;
 entry:
   %v0 = call i32 @llvm.convergent()


        


More information about the llvm-commits mailing list