diff options
| author | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-05-18 15:57:21 +0000 |
|---|---|---|
| committer | Matt Arsenault <Matthew.Arsenault@amd.com> | 2016-05-18 15:57:21 +0000 |
| commit | 891fccc0c178f6b6cc6b024945d8311cb21d864b (patch) | |
| tree | ac2f04f7cffc1860f2d4810a49693fc4d10f7f55 /llvm/lib/Target | |
| parent | 71fa1f375e5aef9a0bde52c60f91b21553411329 (diff) | |
| download | bcm5719-llvm-891fccc0c178f6b6cc6b024945d8311cb21d864b.tar.gz bcm5719-llvm-891fccc0c178f6b6cc6b024945d8311cb21d864b.zip | |
AMDGPU: Handle alloca promoting with null operands
If the second pointer in a multi-pointer instruction is
a constant, we can replace the type.
llvm-svn: 269945
Diffstat (limited to 'llvm/lib/Target')
| -rw-r--r-- | llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp | 39 |
1 files changed, 37 insertions, 2 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp index 3b88bc663d6..134ade765eb 100644 --- a/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp +++ b/llvm/lib/Target/AMDGPU/AMDGPUPromoteAlloca.cpp @@ -510,6 +510,9 @@ bool AMDGPUPromoteAlloca::binaryOpIsDerivedFromSameAlloca(Value *BaseAlloca, if (Val == OtherOp) OtherOp = Inst->getOperand(OpIdx1); + if (isa<ConstantPointerNull>(OtherOp)) + return true; + Value *OtherObj = GetUnderlyingObject(OtherOp, *DL); if (!isa<AllocaInst>(OtherObj)) return false; @@ -573,6 +576,9 @@ bool AMDGPUPromoteAlloca::collectUsesWithPtrTypes( if (ICmpInst *ICmp = dyn_cast<ICmpInst>(UseInst)) { if (!binaryOpIsDerivedFromSameAlloca(BaseAlloca, Val, ICmp, 0, 1)) return false; + + // May need to rewrite constant operands. + WorkList.push_back(ICmp); } if (!User->getType()->isPointerTy()) @@ -713,16 +719,45 @@ void AMDGPUPromoteAlloca::handleAlloca(AllocaInst &I) { for (Value *V : WorkList) { CallInst *Call = dyn_cast<CallInst>(V); if (!Call) { - Type *EltTy = V->getType()->getPointerElementType(); - PointerType *NewTy = PointerType::get(EltTy, AMDGPUAS::LOCAL_ADDRESS); + if (ICmpInst *CI = dyn_cast<ICmpInst>(V)) { + Value *Src0 = CI->getOperand(0); + Type *EltTy = Src0->getType()->getPointerElementType(); + PointerType *NewTy = PointerType::get(EltTy, AMDGPUAS::LOCAL_ADDRESS); + + if (isa<ConstantPointerNull>(CI->getOperand(0))) + CI->setOperand(0, ConstantPointerNull::get(NewTy)); + + if (isa<ConstantPointerNull>(CI->getOperand(1))) + CI->setOperand(1, ConstantPointerNull::get(NewTy)); + + continue; + } // The operand's value should be corrected on its own. if (isa<AddrSpaceCastInst>(V)) continue; + Type *EltTy = V->getType()->getPointerElementType(); + PointerType *NewTy = PointerType::get(EltTy, AMDGPUAS::LOCAL_ADDRESS); + // FIXME: It doesn't really make sense to try to do this for all // instructions. V->mutateType(NewTy); + + // Adjust the types of any constant operands. + if (SelectInst *SI = dyn_cast<SelectInst>(V)) { + if (isa<ConstantPointerNull>(SI->getOperand(1))) + SI->setOperand(1, ConstantPointerNull::get(NewTy)); + + if (isa<ConstantPointerNull>(SI->getOperand(2))) + SI->setOperand(2, ConstantPointerNull::get(NewTy)); + } else if (PHINode *Phi = dyn_cast<PHINode>(V)) { + for (unsigned I = 0, E = Phi->getNumIncomingValues(); I != E; ++I) { + if (isa<ConstantPointerNull>(Phi->getIncomingValue(I))) + Phi->setIncomingValue(I, ConstantPointerNull::get(NewTy)); + } + } + continue; } |

