Skip to content

Commit

Permalink
[GVN] Do not combine convergent calls in GVN/NewGVN
Browse files Browse the repository at this point in the history
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
  • Loading branch information
jayfoad committed May 19, 2023
1 parent 890c76a commit c86a1e6
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 5 deletions.
11 changes: 8 additions & 3 deletions llvm/lib/Transforms/Scalar/GVN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 different basic
// blocks.
if (C->isConvergent()) {
valueNumbering[C] = nextValueNumber;
return nextValueNumber++;
}

if (AA->doesNotAccessMemory(C)) {
Expression exp = createExpr(C);
uint32_t e = assignExpNewValueNum(exp).first;
Expand Down Expand Up @@ -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);
Expand Down
6 changes: 6 additions & 0 deletions llvm/lib/Transforms/Scalar/NewGVN.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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 different basic
// blocks.
if (CI->isConvergent())
return ExprResult::none();

if (AA->doesNotAccessMemory(CI)) {
return ExprResult::some(
createCallExpression(CI, TOPClass->getMemoryLeader()));
Expand Down
4 changes: 3 additions & 1 deletion llvm/test/Transforms/GVN/convergent.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 3 additions & 1 deletion llvm/test/Transforms/NewGVN/convergent.ll
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down

0 comments on commit c86a1e6

Please sign in to comment.