diff --git a/llvm/include/llvm/ADT/GenericUniformityImpl.h b/llvm/include/llvm/ADT/GenericUniformityImpl.h --- a/llvm/include/llvm/ADT/GenericUniformityImpl.h +++ b/llvm/include/llvm/ADT/GenericUniformityImpl.h @@ -1147,9 +1147,11 @@ void GenericUniformityAnalysisImpl::print(raw_ostream &OS) const { bool haveDivergentArgs = false; - if (DivergentValues.empty()) { - assert(DivergentTermBlocks.empty()); - assert(DivergentExitCycles.empty()); + // Control flow instructions may be divergent even if their inputs are + // uniform. Thus, although exceedingly rare, it is possible to have a program + // with no divergent values but with divergent control structures. + if (DivergentValues.empty() && DivergentTermBlocks.empty() && + DivergentExitCycles.empty()) { OS << "ALL VALUES UNIFORM\n"; return; } diff --git a/llvm/lib/Target/AMDGPU/SIInstructions.td b/llvm/lib/Target/AMDGPU/SIInstructions.td --- a/llvm/lib/Target/AMDGPU/SIInstructions.td +++ b/llvm/lib/Target/AMDGPU/SIInstructions.td @@ -397,6 +397,7 @@ let Constraints = ""; let Size = 12; let hasSideEffects = 1; + let IsNeverUniform = 1; } def SI_ELSE : CFPseudoInstSI < @@ -404,6 +405,7 @@ (ins SReg_1:$src, brtarget:$target), [], 1, 1> { let Size = 12; let hasSideEffects = 1; + let IsNeverUniform = 1; } def SI_WATERFALL_LOOP : CFPseudoInstSI < diff --git a/llvm/test/Analysis/UniformityAnalysis/AMDGPU/MIR/control-flow-intrinsics.mir b/llvm/test/Analysis/UniformityAnalysis/AMDGPU/MIR/control-flow-intrinsics.mir new file mode 100644 --- /dev/null +++ b/llvm/test/Analysis/UniformityAnalysis/AMDGPU/MIR/control-flow-intrinsics.mir @@ -0,0 +1,39 @@ +# RUN: llc -mtriple=amdgcn-- -mcpu=gfx900 -run-pass=print-machine-uniformity -o - %s 2>&1 | FileCheck %s + +--- +name: f1 +body: | + ; CHECK-LABEL: MachineUniformityInfo for function: f1 + bb.0: + successors: %bb.1, %bb.2 + + ; CHECK-NOT: DIVERGENT: %1 + %1:sreg_64(s64) = G_IMPLICIT_DEF + ; CHECK: DIVERGENT: {{.*}} SI_IF + %2:sreg_64 = SI_IF %1, %bb.2, implicit-def $exec, implicit-def $scc, implicit $exec + + bb.1: + SI_RETURN + + bb.2: + G_BR %bb.1 + +... + +--- +name: f2 +body: | + ; CHECK-LABEL: MachineUniformityInfo for function: f2 + bb.0: + successors: %bb.1, %bb.2 + + ; CHECK-NOT: DIVERGENT: %1 + %1:sreg_64(s64) = G_IMPLICIT_DEF + ; CHECK: DIVERGENT: {{.*}} SI_ELSE + %2:sreg_64 = SI_ELSE %1, %bb.2, implicit-def $exec, implicit-def $scc, implicit $exec + + bb.1: + SI_RETURN + + bb.2: + G_BR %bb.1