From cf2dc92ae5d8c0fc0fb70c00079690fbb35cdbcf Mon Sep 17 00:00:00 2001 From: Anastasia Bodrova Date: Mon, 1 Sep 2025 10:03:34 +0000 Subject: [PATCH] Changes in code. --- IGC/Compiler/CISACodeGen/DeSSA.cpp | 2 +- .../CISACodeGen/VariableReuseAnalysis.cpp | 72 +++++++-------- .../CISACodeGen/VariableReuseAnalysis.hpp | 4 +- .../EmitVISAPass/inline_asm_vectoralias.ll | 89 ------------------- 4 files changed, 36 insertions(+), 131 deletions(-) delete mode 100644 IGC/Compiler/tests/EmitVISAPass/inline_asm_vectoralias.ll diff --git a/IGC/Compiler/CISACodeGen/DeSSA.cpp b/IGC/Compiler/CISACodeGen/DeSSA.cpp index 1f386f0ca..263e21aea 100644 --- a/IGC/Compiler/CISACodeGen/DeSSA.cpp +++ b/IGC/Compiler/CISACodeGen/DeSSA.cpp @@ -1542,7 +1542,7 @@ bool DeSSA::isAliasee(Value *V) const { // c = 2 // ... // L: = a -// = c +// = b // // In this case, if a is aliased to b, a would get 2 at L, but the correct // value should be 1. In order to find out if a can be aliased to b, it diff --git a/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.cpp b/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.cpp index 72ca0b44f..5165a6bb8 100644 --- a/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.cpp +++ b/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.cpp @@ -887,16 +887,16 @@ bool VariableReuseAnalysis::getAllInsEltsIfAvailable(InsertElementInst *FirstIEI IGC_ASSERT_MESSAGE(IEI_ix < nelts, "ICE: IEI's index out of bound!"); SVecInsEltInfo &InsEltInfo = AllIEIs[IEI_ix]; if (InsEltInfo.IEI) { - // This element is inserted more than once, skip. + // One element is inserted more than once, skip. return false; } InsEltInfo.IEI = I; InsEltInfo.Elt = E; InsEltInfo.FromVec = V; InsEltInfo.FromVec_eltIx = V_ix; - - // So far, E is never nullptr (could be in the future) - InsEltInfo.EEI = dyn_cast_or_null(E); + if (E) { + InsEltInfo.EEI = dyn_cast(E); + } if (!I->hasOneUse()) { break; @@ -923,24 +923,19 @@ bool VariableReuseAnalysis::getAllInsEltsIfAvailable(InsertElementInst *FirstIEI if (tV == nullptr) return false; - // Expect all IEIs are in the same DeSSA CC (DeSSA special-handles IEIs) + // Expect node values for all IEIs are identical. In general, if they + // are in the same DeSSA CC, that would be fine. Value *tV_nv = m_DeSSA->getNodeValue(tV); if (V_root != getRootValue(tV_nv)) return false; Value *E = AllIEIs[i].Elt; - if (!E || isa(E)) { - // constant is okay for either non-uniform or uniform. - continue; - } Value *FromVec = AllIEIs[i].FromVec; - if (FromVec) { - Value *FromVec_nv = m_DeSSA->getNodeValue(FromVec); - // check if FromVec has been coalesced with IEI already by DeSSA. - // (Wouldn't happen under current DeSSA, but might happen in future) - if (V_root == getRootValue(FromVec_nv)) - return false; - } + Value *FromVec_nv = m_DeSSA->getNodeValue(FromVec); + // check if FromVec has been coalesced with IEI already by DeSSA. + // (Wouldn't happen under current DeSSA, but might happen in future) + if (V_root == getRootValue(FromVec_nv)) + return false; // Make sure FromVec or E have the same uniformness as V. if ((E && V_dep != m_WIA->whichDepend(E)) || (FromVec && V_dep != m_WIA->whichDepend(FromVec))) @@ -974,13 +969,17 @@ Value *VariableReuseAnalysis::traceAliasValue(Value *V) { } // -// Returns true if there is the following pattern; otherwise return false. +// Returns true if the following is true // IEI = insertElement Vec, S, -// 1. S is from another vector V. -// S = extractElement V, -// In this case, S is the element denoted by (V, V_ix) -// 2. otherwise, V=nullptr, V_ix=0. -// S is a candidate and could be alias to the vector. +// Return false, otherwise. +// +// When the above condition is true, V and V_ix are used for the +// following cases: +// 1. S is from another vector V. +// S = extractElement V, +// S is the element denoted by (V, V_ix) +// 2. otherwise, V=nullptr, V_ix=0. +// S is a candidate inserted and could be alias to the vector. // // Input: IEI // Output: IEI_ix, S, V, V_ix @@ -1000,9 +999,9 @@ bool VariableReuseAnalysis::getElementValue(InsertElementInst *IEI, int &IEI_ix, IEI_ix = (int)CI->getZExtValue(); Value *elem0 = IEI->getOperand(1); - if (hasBeenPayloadCoalesced(elem0) || isOrCoalescedWithArg(elem0)) { - // If elem0 has been payload-coalesced or it has been aliased to - // an argument, skip it. + if (hasBeenPayloadCoalesced(elem0) || isa(elem0) || isOrCoalescedWithArg(elem0)) { + // If elem0 has been payload-coalesced, is constant, + // or it has been aliased to an argument, skip it. return false; } @@ -1047,10 +1046,11 @@ void VariableReuseAnalysis::InsertElementAliasing(Function *F) { // IGC Key VectorAlias controls vectorAlias optimiation. // - // VectorAlias (also from m_pCtx->getVectorCoalescingControl()) - // 0x0: disable vector aliasing - // 0x1: subvec aliasing for isolated values (getRootValue()=null) - // 0x2: subvec aliasing for both isolated and non-isolated value) + // Do it if VectorAlias != 0. + // VectorAlias=0x1: subvec aliasing for isolated values + // (getRootValue()=null) + // =0x2: subvec aliasing for both isolated and non-isolated + // value) const auto control = (m_pCtx->getVectorCoalescingControl() & 0x3); // To avoid increasing GRF pressure, skip if F is too large or not an entry const int32_t NumBBThreshold = IGC_GET_FLAG_VALUE(VectorAliasBBThreshold); @@ -1253,7 +1253,6 @@ bool VariableReuseAnalysis::processInsertTo(BasicBlock *BB, VecInsEltInfoTy &All isSubCandidate = false; } - // So far, Elt is never nullptr (could be in the future) if (Elt && Sub == nullptr && skipScalarAliaser(BB, Elt)) { // Skip scalar coalescing isSubCandidate = false; @@ -1434,11 +1433,8 @@ VariableReuseAnalysis::AState VariableReuseAnalysis::getCandidateStateUse(Value } } else if (StoreInst *SI = dyn_cast(Val)) { retSt = AState::TARGET; - } else if (CallInst *CallI = dyn_cast(Val)) { - if (CallI->isInlineAsm()) - retSt = AState::TARGET; - else - return AState::SKIP; + } else if (isa(Val)) { + return AState::SKIP; } } return retSt; @@ -1464,9 +1460,7 @@ VariableReuseAnalysis::AState VariableReuseAnalysis::getCandidateStateDef(Value } } else if (LoadInst *SI = dyn_cast(Val)) { return AState::TARGET; - } else if (CallInst *CallI = dyn_cast(Val)) { - if (CallI->isInlineAsm()) - return AState::TARGET; + } else if (isa(Val)) { return AState::SKIP; } return AState::OK; @@ -1474,7 +1468,7 @@ VariableReuseAnalysis::AState VariableReuseAnalysis::getCandidateStateDef(Value // Vector alias disables extractMask optimization. This function // checks if extractMask optim can be applied. And the caller -// will decide whether to favor extractMask optimization or not. +// will decide whether to favor extractMask optimization. bool VariableReuseAnalysis::isExtractMaskCandidate(Value *V) const { auto BIT = [](int n) { return (uint32_t)(1 << n); }; diff --git a/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.hpp b/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.hpp index 612ca1df3..2ade6f51d 100644 --- a/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.hpp +++ b/IGC/Compiler/CISACodeGen/VariableReuseAnalysis.hpp @@ -131,8 +131,8 @@ struct SVecInsEltInfo { llvm::InsertElementInst *IEI; llvm::Value *Elt; - // EEI, if not nullptr, is used as scalar operand of IEI and is the same as - // (FromVec, FromVec_eltIx). + // If Elt is null, EEI must not be null. EEI is used as scalar operand + // in IEI and is the same as (FromVec, FromVec_eltIx). llvm::ExtractElementInst *EEI; llvm::Value *FromVec; int FromVec_eltIx; diff --git a/IGC/Compiler/tests/EmitVISAPass/inline_asm_vectoralias.ll b/IGC/Compiler/tests/EmitVISAPass/inline_asm_vectoralias.ll deleted file mode 100644 index ea12ea04c..000000000 --- a/IGC/Compiler/tests/EmitVISAPass/inline_asm_vectoralias.ll +++ /dev/null @@ -1,89 +0,0 @@ -;=========================== begin_copyright_notice ============================ -; -; Copyright (C) 2023 Intel Corporation -; -; SPDX-License-Identifier: MIT -; -;============================ end_copyright_notice ============================= - -; To vector alias on inline asm - -; REQUIRES: llvm-14-plus, regkeys - -; RUN: igc_opt --opaque-pointers --CheckInstrTypes --igc-update-instrtypes-on-run -inputocl --neo \ -; RUN: -platformpvc -igc-emit-visa -regkey DumpVISAASMToConsole,VectorAlias=1 -simd-mode 16 %s \ -; RUN: | FileCheck %s - -; CHECK-LABEL: .function -; CHECK: lsc_load_block2d.ugm (M1, 1) [[INPUT:.*]]:d8.16x8nt flat[{{.+}}] -; CHECK: mov (M1_NM, 16) [[OUTPUT:.*]](0,0)<2> [[INPUT]](0,0)<4;1,0> -; CHECK: mov (M1_NM, 16) [[OUTPUT]](0,1)<2> [[INPUT]](0,1)<4;1,0> -; CHECK: mov (M1_NM, 16) [[OUTPUT]](1,0)<2> [[INPUT]](0,2)<4;1,0> -; CHECK: mov (M1_NM, 16) [[OUTPUT]](1,1)<2> [[INPUT]](0,3)<4;1,0> -; CHECK: mov (M1, 16) [[OUTPUT]](2,0)<1> 0x0:w -; CHECK: mov (M1, 16) [[OUTPUT]](2,16)<1> 0x0:w -; CHECK: mov (M1, 16) [[OUTPUT]](3,0)<1> 0x0:w -; CHECK: mov (M1, 16) [[OUTPUT]](3,16)<1> 0x0:w -; CHECK: lsc_store_block2d.ugm (M1, 1) flat[{{.+}}] [[OUTPUT]]:d16.16x8nn -; CHECK: ret (M1, 1) - -; Function Attrs: convergent nounwind null_pointer_is_valid -define spir_kernel void @test(i8 addrspace(1)* align 1 %a, i16 addrspace(1)* align 2 %b, <8 x i32> %r0, <8 x i32> %payloadHeader, i8 addrspace(2)* %constBase, i32 %bufferOffset, i32 %bufferOffset1) { -entry: - %0 = call <8 x i8> asm "lsc_load_block2d.ugm (M1, 1) $0:d8.16x8nt flat[$1,15,15,15,0,0]", "=rw,rw.u"(i8 addrspace(1)* %a) - %1 = extractelement <8 x i8> %0, i32 0 - %2 = insertelement <4 x i8> undef, i8 %1, i32 0 - %3 = extractelement <8 x i8> %0, i32 1 - %4 = insertelement <4 x i8> %2, i8 %3, i32 1 - %5 = extractelement <8 x i8> %0, i32 2 - %6 = insertelement <4 x i8> %4, i8 %5, i32 2 - %7 = extractelement <8 x i8> %0, i32 3 - %8 = insertelement <4 x i8> %6, i8 %7, i32 3 - %9 = call <4 x i16> asm "mov (M1_NM, 16) $0(0,0)<2> $1(0,0)<4;1,0>\0Amov (M1_NM, 16) $0(0,1)<2> $1(0,1)<4;1,0>\0Amov (M1_NM, 16) $0(1,0)<2> $1(0,2)<4;1,0>\0Amov (M1_NM, 16) $0(1,1)<2> $1(0,3)<4;1,0>\0A", "=rw,rw"(<4 x i8> %8) - %10 = extractelement <4 x i16> %9, i32 0 - %11 = extractelement <4 x i16> %9, i32 1 - %12 = extractelement <4 x i16> %9, i32 2 - %13 = extractelement <4 x i16> %9, i32 3 - %14 = insertelement <8 x i16> undef, i16 %10, i32 0 - %15 = insertelement <8 x i16> %14, i16 %11, i32 1 - %16 = insertelement <8 x i16> %15, i16 %12, i32 2 - %17 = insertelement <8 x i16> %16, i16 %13, i32 3 - %18 = insertelement <8 x i16> %17, i16 0, i32 4 - %19 = insertelement <8 x i16> %18, i16 0, i32 5 - %20 = insertelement <8 x i16> %19, i16 0, i32 6 - %21 = insertelement <8 x i16> %20, i16 0, i32 7 - call void asm sideeffect "lsc_store_block2d.ugm (M1, 1) flat[$1,15,15,15,0,0] $0:d16.16x8nn", "rw,rw.u"(<8 x i16> %21, i16 addrspace(1)* %b) - ret void -} - - -!igc.functions = !{!0} -!IGCMetadata = !{!13} - -!0 = !{void (i8 addrspace(1)*, i16 addrspace(1)*, <8 x i32>, <8 x i32>, i8 addrspace(2)*, i32, i32)* @test, !1} -!1 = !{!2, !3} -!2 = !{!"function_type", i32 0} -!3 = !{!"sub_group_size", i32 16} -!13 = !{!"ModuleMD", !14} -!14 = !{!"FuncMD", !15, !16} -!15 = !{!"FuncMDMap[0]", void (i8 addrspace(1)*, i16 addrspace(1)*, <8 x i32>, <8 x i32>, i8 addrspace(2)*, i32, i32)* @test} -!16 = !{!"FuncMDValue[0]", !100, !226} -!100 = !{!"resAllocMD", !183, !184, !185, !186} -!183 = !{!"uavsNumType", i32 0} -!184 = !{!"srvsNumType", i32 0} -!185 = !{!"samplersNumType", i32 0} -!186 = !{!"argAllocMDList", !187, !191, !192, !193, !194, !195, !196} -!187 = !{!"argAllocMDListVec[0]", !188, !189, !190} -!188 = !{!"type", i32 0} -!189 = !{!"extensionType", i32 -1} -!190 = !{!"indexType", i32 -1} -!191 = !{!"argAllocMDListVec[1]", !188, !189, !190} -!192 = !{!"argAllocMDListVec[2]", !188, !189, !190} -!193 = !{!"argAllocMDListVec[3]", !188, !189, !190} -!194 = !{!"argAllocMDListVec[4]", !188, !189, !190} -!195 = !{!"argAllocMDListVec[5]", !188, !189, !190} -!196 = !{!"argAllocMDListVec[6]", !188, !189, !190} -!226 = !{!"m_OpenCLArgTypeQualifiers", !227, !228} -!227 = !{!"m_OpenCLArgTypeQualifiersVec[0]", !""} -!228 = !{!"m_OpenCLArgTypeQualifiersVec[1]", !""} -