mirror of
				https://github.com/intel/intel-graphics-compiler.git
				synced 2025-10-30 08:18:26 +08:00 
			
		
		
		
	[Autobackout][FunctionalRegression]Revert of change: 4235871241: Lower loads using PHI instructions
				
					
				
			Lowers loads using PHI instructions to incoming blocks to avoid
    uncessary address space casts.
			
			
This commit is contained in:
		| @ -1,6 +1,6 @@ | ||||
| /*========================== begin_copyright_notice ============================ | ||||
|  | ||||
| Copyright (C) 2017-2025 Intel Corporation | ||||
| Copyright (C) 2017-2021 Intel Corporation | ||||
|  | ||||
| SPDX-License-Identifier: MIT | ||||
|  | ||||
| @ -13,10 +13,6 @@ SPDX-License-Identifier: MIT | ||||
|  | ||||
| #include "common/LLVMWarningsPush.hpp" | ||||
| #include <llvm/Pass.h> | ||||
| #include <llvm/ADT/SmallSet.h> | ||||
| #include <llvm/IR/Instructions.h> | ||||
| #include <llvm/ADT/STLExtras.h> | ||||
| #include <llvm/IR/BasicBlock.h> | ||||
| #include "common/LLVMWarningsPop.hpp" | ||||
|  | ||||
| using namespace llvm; | ||||
| @ -58,115 +54,11 @@ IGC_INITIALIZE_PASS_BEGIN(AddrSpaceCastFixing, PASS_FLAG, PASS_DESC, PASS_CFG_ON | ||||
| IGC_INITIALIZE_PASS_END(AddrSpaceCastFixing, PASS_FLAG, PASS_DESC, PASS_CFG_ONLY, PASS_ANALYSIS) | ||||
| } // namespace IGC | ||||
|  | ||||
| static bool isPhiUsingDifferentAddrSpaces(PHINode *PHI) { | ||||
|   SmallSet<unsigned, 4> AddrSpaces; | ||||
|   for (auto &Incoming : PHI->incoming_values()) { | ||||
|     if (auto *AddrSpaceCast = dyn_cast<AddrSpaceCastInst>(Incoming)) { | ||||
|       AddrSpaces.insert(AddrSpaceCast->getSrcAddressSpace()); | ||||
|     } else if (auto *GetElementPtr = dyn_cast<GetElementPtrInst>(Incoming)) { | ||||
|       AddrSpaces.insert(GetElementPtr->getPointerAddressSpace()); | ||||
|     } | ||||
|   } | ||||
|   return AddrSpaces.size() > 1; | ||||
| } | ||||
|  | ||||
| static bool isPhiUseLowerable(PHINode *PHI) { | ||||
|   if (!PHI->hasOneUse()) { | ||||
|     return false; | ||||
|   } | ||||
|   if (isa<LoadInst>(*(PHI->user_begin()))) { | ||||
|     return true; | ||||
|   } | ||||
|   return isa<BitCastInst>(*(PHI->user_begin())) && PHI->user_begin()->hasOneUse() && | ||||
|          isa<LoadInst>(*(PHI->user_begin()->user_begin())); | ||||
| } | ||||
|  | ||||
| static void lowerLoadsfromPHI(PHINode *PHI) { | ||||
|   SmallVector<Instruction *, 8> ToErase; | ||||
|   SmallVector<Instruction *, 2> InsertChain; | ||||
|   LoadInst *PHILoad = nullptr; | ||||
|   if (isa<LoadInst>(*(PHI->user_begin()))) { | ||||
|     InsertChain.push_back(cast<Instruction>(*PHI->user_begin())); | ||||
|     PHILoad = cast<LoadInst>(*PHI->user_begin()); | ||||
|   } else { | ||||
|     InsertChain.push_back(cast<Instruction>(*PHI->user_begin())); | ||||
|     InsertChain.push_back(cast<Instruction>(*PHI->user_begin()->user_begin())); | ||||
|     PHILoad = cast<LoadInst>(*PHI->user_begin()->user_begin()); | ||||
|   } | ||||
|   IGC_ASSERT_MESSAGE(PHILoad != nullptr, "Expecting a load instruction"); | ||||
|   llvm::append_range(ToErase, llvm::reverse(InsertChain)); | ||||
|   ToErase.push_back(cast<Instruction>(PHI)); | ||||
|  | ||||
|   SmallVector<Instruction *, 8> NewLoads; | ||||
|   for (auto &Incoming : PHI->incoming_values()) { | ||||
|     auto *LoadSource = cast<Instruction>(Incoming); | ||||
|     auto *AddrSpaceCast = dyn_cast<AddrSpaceCastInst>(Incoming); | ||||
|  | ||||
|     for (auto *I : InsertChain) { | ||||
|  | ||||
|       if (AddrSpaceCast) { | ||||
|         IRBuilder<> Builder(LoadSource); | ||||
|         if (isa<BitCastInst>(I)) { | ||||
|           auto *NewBitcast = Builder.CreateBitCast( | ||||
|               AddrSpaceCast->getOperand(0), PointerType::get(PHILoad->getType(), AddrSpaceCast->getSrcAddressSpace())); | ||||
|           LoadSource = cast<Instruction>(NewBitcast); | ||||
|         } else if (isa<LoadInst>(I)) { | ||||
|           auto *NewLoad = Builder.CreateLoad(PHILoad->getType(), AddrSpaceCast->getOperand(0)); | ||||
|           NewLoad->copyMetadata(*I); | ||||
|           LoadSource = NewLoad; | ||||
|           NewLoads.push_back(NewLoad); | ||||
|         } | ||||
|         ToErase.push_back(AddrSpaceCast); | ||||
|         AddrSpaceCast = nullptr; | ||||
|         continue; | ||||
|       } | ||||
|  | ||||
|       Instruction *NewInst = I->clone(); | ||||
|       NewInst->setOperand(0, LoadSource); | ||||
|       NewInst->insertAfter(LoadSource); | ||||
|       LoadSource = NewInst; | ||||
|       if (isa<LoadInst>(NewInst)) { | ||||
|         NewLoads.push_back(NewInst); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|   IRBuilder<> Builder(PHI->getParent(), PHI->getParent()->begin()); | ||||
|   auto *NewPHI = Builder.CreatePHI(PHILoad->getType(), NewLoads.size()); | ||||
|  | ||||
|   for_each(NewLoads, [&NewPHI](Instruction *I) { NewPHI->addIncoming(I, I->getParent()); }); | ||||
|   PHILoad->replaceAllUsesWith(NewPHI); | ||||
|  | ||||
|   for_each(ToErase, [](Instruction *I) { I->eraseFromParent(); }); | ||||
| } | ||||
|  | ||||
| static bool removeAddrSpaceCastsFromPhiIncomingBBs(Function &F) { | ||||
|   bool Changed = false; | ||||
|  | ||||
|   SmallVector<PHINode *, 8> PhisToModify; | ||||
|   for (auto &I : instructions(F)) { | ||||
|     if (auto *PHI = dyn_cast<PHINode>(&I)) { | ||||
|       if (isPhiUsingDifferentAddrSpaces(PHI) && isPhiUseLowerable(PHI)) { | ||||
|         PhisToModify.push_back(PHI); | ||||
|       } | ||||
|     } | ||||
|   } | ||||
|  | ||||
|   for (auto *PHI : PhisToModify) { | ||||
|     lowerLoadsfromPHI(PHI); | ||||
|     Changed = true; | ||||
|   } | ||||
|  | ||||
|   return Changed; | ||||
| } | ||||
|  | ||||
| bool AddrSpaceCastFixing::runOnFunction(Function &F) { | ||||
|   bool Changed = false; | ||||
|   for (auto &BB : F) { | ||||
|   for (auto &BB : F) | ||||
|     Changed |= fixOnBasicBlock(&BB); | ||||
|   } | ||||
|   if (IGC_IS_FLAG_ENABLED(AddressSpacePhiPropagation)) { | ||||
|     Changed |= removeAddrSpaceCastsFromPhiIncomingBBs(F); | ||||
|   } | ||||
|  | ||||
|   return Changed; | ||||
| } | ||||
|  | ||||
|  | ||||
| @ -367,7 +367,7 @@ void AddAnalysisPasses(CodeGenContext &ctx, IGCPassManager &mpm) { | ||||
|     mpm.add(new IGCRegisterPressurePrinter("final")); | ||||
|   // Let Layout be the last pass before Emit Pass | ||||
|   mpm.add(new Layout()); | ||||
|   if (IGC_IS_FLAG_ENABLED(EnableDropTargetBBs)) { | ||||
|   if(IGC_IS_FLAG_ENABLED(EnableDropTargetBBs)) { | ||||
|     mpm.add(new DropTargetBBs()); | ||||
|   } | ||||
|  | ||||
| @ -569,10 +569,6 @@ void AddLegalizationPasses(CodeGenContext &ctx, IGCPassManager &mpm, PSSignature | ||||
|     mpm.add(new PromoteResourceToDirectAS()); | ||||
|   } | ||||
|  | ||||
|   if (!isOptDisabled) { | ||||
|     mpm.add(createPruneUnusedArgumentsPass()); | ||||
|   } | ||||
|  | ||||
|   if (ctx.m_instrTypes.hasReadOnlyArray) { | ||||
|     mpm.add(createDeadCodeEliminationPass()); | ||||
|     mpm.add(createSROAPass()); | ||||
|  | ||||
| @ -1,60 +0,0 @@ | ||||
| ;=========================== begin_copyright_notice ============================ | ||||
| ; | ||||
| ; Copyright (C) 2022-2025 Intel Corporation | ||||
| ; | ||||
| ; SPDX-License-Identifier: MIT | ||||
| ; | ||||
| ;============================ end_copyright_notice ============================= | ||||
| ; | ||||
| ; RUN: igc_opt  --opaque-pointers --igc-addrspacecast-fix -S < %s | FileCheck %s | ||||
| ; ------------------------------------------------ | ||||
| ; FixAddrSpaceCast | ||||
| ; ------------------------------------------------ | ||||
| ; This test checks that loads are correctly lowered from blocks with phi nodes into incoming blocks, | ||||
| ; to avoid extra address space casts. | ||||
| ; ------------------------------------------------ | ||||
|  | ||||
| ; CHECK-LABEL: @testFn | ||||
| ; CHECK-NOT: addrspacecast | ||||
|  | ||||
| ; CHECK-LABEL: cond.true3442: | ||||
| ; CHECK: [[T0:%.*]] = load i32, ptr addrspace(4) %gep.res | ||||
| ; CHECK: br label %cond.end3465 | ||||
|  | ||||
| ; CHECK-LABEL: cond.false3459 | ||||
| ; CHECK:  [[T1:%.*]] = load i32, ptr addrspace(3) %arrayidx3464 | ||||
| ; CHECK:  br label %cond.end3465 | ||||
|  | ||||
| ; CHECK-LABEL: cond.end3465: | ||||
| ; CHECK: [[T3:%.*]] = phi i32 [ [[T0]], %cond.true3442 ], [ [[T1]], %cond.false3459 ] | ||||
| ; CHECK: icmp sgt i32 [[T3]], -1 | ||||
|  | ||||
| define i1 @testFn(ptr addrspace(3) %arrayidx3464, ptr addrspace(1) %globalArgs, i64 %idx.ext.i12415) #0 { | ||||
|  | ||||
| entry: | ||||
|   %test = icmp sgt i64 %idx.ext.i12415, -1 | ||||
|   br i1 %test, label %cond.true3442, label %cond.false3459 | ||||
|  | ||||
| cond.true3442: | ||||
|   %global.ptr = load ptr addrspace(4), ptr addrspace(1) %globalArgs, align 16 | ||||
|   %gep.res = getelementptr inbounds i8, ptr addrspace(4) %global.ptr, i64 %idx.ext.i12415 | ||||
|   br label %cond.end3465 | ||||
|  | ||||
| cond.false3459: | ||||
|   %addr.res = addrspacecast ptr addrspace(3) %arrayidx3464 to ptr addrspace(4) | ||||
|   br label %cond.end3465 | ||||
|  | ||||
| cond.end3465: | ||||
|   %cond3466.in = phi ptr addrspace(4) [ %gep.res, %cond.true3442 ], [ %addr.res, %cond.false3459 ] | ||||
|   %cond3466 = load i32, ptr addrspace(4) %cond3466.in, align 4 | ||||
|   %test2 = icmp sgt i32 %cond3466, -1 | ||||
|   br i1 %test2, label %while.cond3471.preheader.exitStub, label %if.end3568.exitStub | ||||
|  | ||||
| while.cond3471.preheader.exitStub: | ||||
|   ret i1 true | ||||
|  | ||||
| if.end3568.exitStub: | ||||
|   ret i1 false | ||||
| } | ||||
|  | ||||
| attributes #0 = { noinline nounwind } | ||||
| @ -1,65 +0,0 @@ | ||||
| ;=========================== begin_copyright_notice ============================ | ||||
| ; | ||||
| ; Copyright (C) 2022-2025 Intel Corporation | ||||
| ; | ||||
| ; SPDX-License-Identifier: MIT | ||||
| ; | ||||
| ;============================ end_copyright_notice ============================= | ||||
| ; | ||||
| ; RUN: igc_opt --typed-pointers --igc-addrspacecast-fix -S < %s | FileCheck %s | ||||
| ; ------------------------------------------------ | ||||
| ; FixAddrSpaceCast | ||||
| ; ------------------------------------------------ | ||||
| ; This test checks that loads are correctly lowered from blocks with phi nodes into incoming blocks, | ||||
| ; to avoid extra address space casts. | ||||
| ; ------------------------------------------------ | ||||
|  | ||||
| ; CHECK-LABEL: @testFn | ||||
| ; CHECK-NOT: addrspacecast | ||||
|  | ||||
| ; CHECK-LABEL: cond.true3442: | ||||
| ; CHECK: [[T1:%.*]] = bitcast i8 addrspace(4)* %gep.res to i32 addrspace(4)* | ||||
| ; CHECK: [[T2:%.*]] = load i32, i32 addrspace(4)* [[T1]], align 4 | ||||
| ; CHECK: br label %cond.end3465 | ||||
|  | ||||
| ; CHECK-LABEL: cond.false3459 | ||||
| ; CHECK:  [[T3:%.*]] = bitcast i8 addrspace(3)* %arrayidx3464 to i32 addrspace(3)* | ||||
| ; CHECK:  [[T4:%.*]] = load i32, i32 addrspace(3)* [[T3]], align 4 | ||||
| ; CHECK:  br label %cond.end3465 | ||||
|  | ||||
| ; CHECK-LABEL: cond.end3465: | ||||
| ; CHECK: [[T5:%.*]] = phi i32 [ [[T2]], %cond.true3442 ], [ [[T4]], %cond.false3459 ] | ||||
| ; CHECK: icmp sgt i32 [[T5]], -1 | ||||
|  | ||||
| define i1 @testFn(i8 addrspace(3)* %arrayidx3464, i8 addrspace(1)* %globalArgs, i64 %idx.ext.i12415) #0 { | ||||
|  | ||||
| entry: | ||||
|   %test = icmp sgt i64 %idx.ext.i12415, -1 | ||||
|   br i1 %test, label %cond.true3442, label %cond.false3459 | ||||
|  | ||||
| cond.true3442: | ||||
|   %arrayidx3450 = getelementptr inbounds i8, i8 addrspace(1)* %globalArgs, i64 896 | ||||
|   %tmp1 = bitcast i8 addrspace(1)* %arrayidx3450 to i8 addrspace(4)* addrspace(1)* | ||||
|   %tmp2 = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(1)* %tmp1, align 16 | ||||
|   %gep.res = getelementptr inbounds i8, i8 addrspace(4)* %tmp2, i64 %idx.ext.i12415 | ||||
|   br label %cond.end3465 | ||||
|  | ||||
| cond.false3459: | ||||
|   %addr.res = addrspacecast i8 addrspace(3)* %arrayidx3464 to i8 addrspace(4)* | ||||
|   br label %cond.end3465 | ||||
|  | ||||
| cond.end3465: | ||||
|   %cond3466.in = phi i8 addrspace(4)* [ %gep.res, %cond.true3442 ], [ %addr.res, %cond.false3459 ] | ||||
|   %cast1 = bitcast i8 addrspace(4)* %cond3466.in to i32 addrspace(4)* | ||||
|   %cond3466 = load i32, i32 addrspace(4)* %cast1, align 4 | ||||
|   %test2 = icmp sgt i32 %cond3466, -1 | ||||
|   br i1 %test2, label %while.cond3471.preheader.exitStub, label %if.end3568.exitStub | ||||
|  | ||||
| while.cond3471.preheader.exitStub: | ||||
|   ret i1 true | ||||
|  | ||||
| if.end3568.exitStub: | ||||
|   ret i1 false | ||||
| } | ||||
|  | ||||
| attributes #0 = { noinline nounwind } | ||||
| @ -1589,8 +1589,6 @@ DECLARE_IGC_REGKEY(bool, RematAllowLoads, false, | ||||
| DECLARE_IGC_REGKEY(bool, DumpRegPressureEstimate, false, "Dump RegPressureEstimate to a file", false) | ||||
| DECLARE_IGC_REGKEY(debugString, DumpRegPressureEstimateFilter, 0, | ||||
|                    "Only dump RegPressureEstimate for functions matching the given regex", false) | ||||
| DECLARE_IGC_REGKEY(bool, AddressSpacePhiPropagation, true, | ||||
|                    "Lower loads from PHI nodes into incoming nodes in case they cause extra address space casts.", false) | ||||
| DECLARE_IGC_REGKEY(bool, VectorizerLog, false, "Dump Vectorizer Log, usefull for analyzing vectorization issues", true) | ||||
| DECLARE_IGC_REGKEY(bool, VectorizerLogToErr, false, "Dump Vectorizer Log to stdErr", true) | ||||
| DECLARE_IGC_REGKEY(bool, EnableReusingXYZWStoreConstPayload, true, "Enable reusing XYZW stores const payload", false) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user
	 sys_igc
					sys_igc