summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target
diff options
context:
space:
mode:
authorMatt Arsenault <Matthew.Arsenault@amd.com>2016-05-18 15:57:21 +0000
committerMatt Arsenault <Matthew.Arsenault@amd.com>2016-05-18 15:57:21 +0000
commit891fccc0c178f6b6cc6b024945d8311cb21d864b (patch)
treeac2f04f7cffc1860f2d4810a49693fc4d10f7f55 /llvm/lib/Target
parent71fa1f375e5aef9a0bde52c60f91b21553411329 (diff)
downloadbcm5719-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.cpp39
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;
}
OpenPOWER on IntegriCloud