[llvm] a585228 - Prevent LICM and machineLICM from hoisting convergent operations
Quentin Colombet via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 6 10:26:52 PST 2020
Author: Quentin Colombet
Date: 2020-11-06T10:26:39-08:00
New Revision: a585228027a0f025011d77916234cfba12e44309
URL: https://github.com/llvm/llvm-project/commit/a585228027a0f025011d77916234cfba12e44309
DIFF: https://github.com/llvm/llvm-project/commit/a585228027a0f025011d77916234cfba12e44309.diff
LOG: Prevent LICM and machineLICM from hoisting convergent operations
Results of convergent operations are implicitly affected by the
enclosing control flows and should not be hoisted out of arbitrary
loops.
Patch by Xiaoqing Wu <xiaoqing_wu at apple.com>
Differential Revision: https://reviews.llvm.org/D90361
Added:
llvm/test/CodeGen/AMDGPU/machinelicm-convergent.mir
llvm/test/Transforms/LICM/convergent.ll
Modified:
llvm/lib/CodeGen/MachineLICM.cpp
llvm/lib/Transforms/Scalar/LICM.cpp
Removed:
################################################################################
diff --git a/llvm/lib/CodeGen/MachineLICM.cpp b/llvm/lib/CodeGen/MachineLICM.cpp
index 8e20541df5ae..19e36669a254 100644
--- a/llvm/lib/CodeGen/MachineLICM.cpp
+++ b/llvm/lib/CodeGen/MachineLICM.cpp
@@ -1044,6 +1044,13 @@ bool MachineLICMBase::IsLICMCandidate(MachineInstr &I) {
!IsGuaranteedToExecute(I.getParent()))
return false;
+ // Convergent attribute has been used on operations that involve inter-thread
+ // communication which results are implicitly affected by the enclosing
+ // control flows. It is not safe to hoist or sink such operations across
+ // control flow.
+ if (I.isConvergent())
+ return false;
+
return true;
}
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 3c9aa946d607..6b8973d3cad7 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -1163,6 +1163,13 @@ bool llvm::canSinkOrHoistInst(Instruction &I, AAResults *AA, DominatorTree *DT,
if (CI->mayThrow())
return false;
+ // Convergent attribute has been used on operations that involve
+ // inter-thread communication which results are implicitly affected by the
+ // enclosing control flows. It is not safe to hoist or sink such operations
+ // across control flow.
+ if (CI->isConvergent())
+ return false;
+
using namespace PatternMatch;
if (match(CI, m_Intrinsic<Intrinsic::assume>()))
// Assumes don't actually alias anything or throw
diff --git a/llvm/test/CodeGen/AMDGPU/machinelicm-convergent.mir b/llvm/test/CodeGen/AMDGPU/machinelicm-convergent.mir
new file mode 100644
index 000000000000..5ac2713f247a
--- /dev/null
+++ b/llvm/test/CodeGen/AMDGPU/machinelicm-convergent.mir
@@ -0,0 +1,32 @@
+# RUN: llc -march=amdgcn -run-pass=early-machinelicm -o - %s | FileCheck %s
+
+# Test to check machine LICM does not hoist convergent instructions,
+# DS_PERMUTE_B32 in this example.
+
+---
+# CHECK-LABEL: name: _amdgpu_cs_main
+# CHECK: bb.1:
+# CHECK: DS_PERMUTE_B32
+
+name: _amdgpu_cs_main
+body: |
+ bb.0:
+ liveins: $vgpr0, $vgpr1
+ successors: %bb.1
+
+ %0:vgpr_32 = COPY $vgpr0
+ %1:vgpr_32 = COPY $vgpr1
+
+ bb.1:
+ successors: %bb.1, %bb.2
+
+ %2:vgpr_32 = DS_PERMUTE_B32 %0, %1, 0, implicit $exec
+ %3:vgpr_32 = V_ADD_CO_U32_e32 %0, %2, implicit-def $vcc, implicit $exec
+ S_CBRANCH_SCC1 %bb.1, implicit undef $scc
+ S_BRANCH %bb.2
+
+ bb.2:
+ $vgpr0 = COPY %3
+ S_ENDPGM 0
+
+...
diff --git a/llvm/test/Transforms/LICM/convergent.ll b/llvm/test/Transforms/LICM/convergent.ll
new file mode 100644
index 000000000000..9ff95bf1d320
--- /dev/null
+++ b/llvm/test/Transforms/LICM/convergent.ll
@@ -0,0 +1,21 @@
+; RUN: opt < %s -S -licm | FileCheck %s
+
+; Check that we do not hoist convergent functions out of loop
+; CHECK: define i32 @test
+; CHECK: loop:
+; CHECK: call i32 @f
+
+define i32 @test(i32* nocapture noalias %x, i32* nocapture %y) {
+entry:
+ br label %loop
+
+loop:
+ %a = call i32 @f() nounwind readnone convergent
+ %exitcond = icmp ne i32 %a, 0
+ br i1 %exitcond, label %end, label %loop
+
+end:
+ ret i32 %a
+}
+
+declare i32 @f() nounwind readnone convergent
More information about the llvm-commits
mailing list