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 @@ -963,7 +963,14 @@ LLVM_DEBUG(dbgs() << "taintAndPushPhiNodes in " << Context.print(&JoinBlock) << "\n"); for (const auto &Phi : JoinBlock.phis()) { - if (ContextT::isConstantValuePhi(Phi)) + // FIXME: The non-undef value is not constant per se; it just happens to be + // uniform and may not dominate this PHI. So assuming that the same value + // reaches along all incoming edges may itself be undefined behaviour. This + // particular interpretation of the undef value was added to + // DivergenceAnalysis in the following review: + // + // https://reviews.llvm.org/D19013 + if (ContextT::isConstantOrUndefValuePhi(Phi)) continue; if (markDivergent(Phi)) Worklist.push_back(&Phi); diff --git a/llvm/include/llvm/CodeGen/MachineSSAContext.h b/llvm/include/llvm/CodeGen/MachineSSAContext.h --- a/llvm/include/llvm/CodeGen/MachineSSAContext.h +++ b/llvm/include/llvm/CodeGen/MachineSSAContext.h @@ -58,7 +58,7 @@ static void appendBlockTerms(SmallVectorImpl &terms, const MachineBasicBlock &block); MachineBasicBlock *getDefBlock(Register) const; - static bool isConstantValuePhi(const MachineInstr &Phi); + static bool isConstantOrUndefValuePhi(const MachineInstr &Phi); Printable print(const MachineBasicBlock *Block) const; Printable print(const MachineInstr *Inst) const; diff --git a/llvm/include/llvm/IR/SSAContext.h b/llvm/include/llvm/IR/SSAContext.h --- a/llvm/include/llvm/IR/SSAContext.h +++ b/llvm/include/llvm/IR/SSAContext.h @@ -63,7 +63,7 @@ const BasicBlock &block); static bool comesBefore(const Instruction *lhs, const Instruction *rhs); - static bool isConstantValuePhi(const Instruction &Instr); + static bool isConstantOrUndefValuePhi(const Instruction &Instr); const BasicBlock *getDefBlock(const Value *value) const; Printable print(const BasicBlock *Block) const; diff --git a/llvm/lib/CodeGen/MachineSSAContext.cpp b/llvm/lib/CodeGen/MachineSSAContext.cpp --- a/llvm/lib/CodeGen/MachineSSAContext.cpp +++ b/llvm/lib/CodeGen/MachineSSAContext.cpp @@ -56,7 +56,7 @@ return RegInfo->getVRegDef(value)->getParent(); } -bool MachineSSAContext::isConstantValuePhi(const MachineInstr &Phi) { +bool MachineSSAContext::isConstantOrUndefValuePhi(const MachineInstr &Phi) { return Phi.isConstantValuePHI(); } diff --git a/llvm/lib/IR/SSAContext.cpp b/llvm/lib/IR/SSAContext.cpp --- a/llvm/lib/IR/SSAContext.cpp +++ b/llvm/lib/IR/SSAContext.cpp @@ -75,9 +75,9 @@ return lhs->comesBefore(rhs); } -bool SSAContext::isConstantValuePhi(const Instruction &Instr) { +bool SSAContext::isConstantOrUndefValuePhi(const Instruction &Instr) { if (auto *Phi = dyn_cast(&Instr)) - return Phi->hasConstantValue(); + return Phi->hasConstantOrUndefValue(); return false; } diff --git a/llvm/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll b/llvm/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll --- a/llvm/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll +++ b/llvm/test/Analysis/DivergenceAnalysis/AMDGPU/phi-undef.ll @@ -1,15 +1,14 @@ -; RUN: opt -mtriple amdgcn-- -passes='print' -disable-output %s 2>&1 | FileCheck %s --check-prefixes=CHECK,LOOPDA -; RUN: opt -mtriple amdgcn-- -passes='print' -disable-output %s 2>&1 | FileCheck %s --check-prefixes=CHECK,CYCLEDA +; RUN: opt -mtriple amdgcn-- -passes='print' -disable-output %s 2>&1 | FileCheck %s +; RUN: opt -mtriple amdgcn-- -passes='print' -disable-output %s 2>&1 | FileCheck %s ; CHECK-LABEL: 'test1': ; CHECK: DIVERGENT: i32 %bound -; CYCLEDA: DIVERGENT: %counter = -; LOOPDA: {{^ *}} %counter = -; CHECK-NEXT: DIVERGENT: %break = icmp sge i32 %counter, %bound -; CYCLEDA: DIVERGENT: %counter.next = -; CYCLEDA: DIVERGENT: %counter.footer = -; LOOPDA: {{^ *}}%counter.next = -; LOOPDA: {{^ *}}%counter.footer = +; CHECK: {{^ *}} %counter = +; CHECK: DIVERGENT: %break = icmp sge i32 %counter, %bound +; CHECK: DIVERGENT: br i1 %break, label %footer, label %body +; CHECK: {{^ *}}%counter.next = +; CHECK: {{^ *}}%counter.footer = +; CHECK: DIVERGENT: br i1 %break, label %end, label %header ; Note: %counter is not divergent!