Skip to content

Commit 0500e3c

Browse files
krystian-andrzejewskisys_zuul
authored andcommitted
Adding support for llvm.canonicalize intrinsic.
Change-Id: Ieed4a6beaf9089ef616071a05110ea88cc4719d0
1 parent 556bd2c commit 0500e3c

File tree

10 files changed

+119
-6
lines changed

10 files changed

+119
-6
lines changed

IGC/Compiler/CISACodeGen/CISABuilder.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4046,7 +4046,8 @@ namespace IGC
40464046
{
40474047
SaveOption(vISA_BXMLEncoder, false);
40484048
}
4049-
if (IGC_IS_FLAG_ENABLED(DisableMixMode))
4049+
if (IGC_IS_FLAG_ENABLED(DisableMixMode) ||
4050+
context->getModuleMetaData()->disableMixMode)
40504051
{
40514052
SaveOption(vISA_DisableMixMode, true);
40524053
}

IGC/Compiler/CISACodeGen/EmitVISAPass.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8004,6 +8004,10 @@ void EmitPass::EmitIntrinsicMessage(llvm::IntrinsicInst* inst)
80048004
emitSqrt(inst);
80058005
break;
80068006

8007+
case Intrinsic::canonicalize:
8008+
emitCanonicalize(inst);
8009+
break;
8010+
80078011
default:
80088012
inst->print(IGC::Debug::ods());
80098013
assert(0 && "unknown intrinsic");
@@ -15655,6 +15659,26 @@ void EmitPass::emitSqrt(Instruction* inst)
1565515659
m_encoder->Sqrt(m_destination, src0);
1565615660
}
1565715661

15662+
void IGC::EmitPass::emitCanonicalize(llvm::Instruction* inst)
15663+
{
15664+
// Force to flush denormal fp value to zero. Select one of two possible solutions:
15665+
// 1. add inputVal, -0.0
15666+
// 2. mul inputVal, 1.0
15667+
// A normalized fp value isn't changed.
15668+
// The operation is done only if particular flags are set.
15669+
// If the instruction should be emitted anyway, flushing a subnormal to zero has to implemented in other way.
15670+
CodeGenContext* pCodeGenContext = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
15671+
bool flushVal = pCodeGenContext->m_floatDenormMode16 == ::IGC::FLOAT_DENORM_FLUSH_TO_ZERO && inst->getType()->isHalfTy();
15672+
flushVal = flushVal || (pCodeGenContext->m_floatDenormMode32 == ::IGC::FLOAT_DENORM_FLUSH_TO_ZERO && inst->getType()->isFloatTy());
15673+
flushVal = flushVal || (pCodeGenContext->m_floatDenormMode64 == ::IGC::FLOAT_DENORM_FLUSH_TO_ZERO && inst->getType()->isDoubleTy());
15674+
if (flushVal)
15675+
{
15676+
CVariable* inputVal = GetSymbol(inst->getOperand(0));
15677+
CVariable* negativeZero = m_currShader->GetScalarConstant(llvm::ConstantFP::get(inst->getType(), -0.0));
15678+
m_encoder->Add(m_destination, inputVal, negativeZero);
15679+
}
15680+
}
15681+
1565815682
// emit llvm.bswap
1565915683
void EmitPass::emitLLVMbswap(IntrinsicInst* inst)
1566015684
{

IGC/Compiler/CISACodeGen/EmitVISAPass.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -407,6 +407,7 @@ namespace IGC
407407
void emitAddPairWithImm(CVariable* Dst, CVariable* Src, CVariable* Imm);
408408

409409
void emitSqrt(llvm::Instruction* inst);
410+
void emitCanonicalize(llvm::Instruction* inst);
410411
void emitRsq(llvm::Instruction* inst);
411412

412413
void emitLLVMbswap(llvm::IntrinsicInst* inst);

IGC/Compiler/CISACodeGen/PatternMatchPass.cpp

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,6 +2993,52 @@ namespace IGC
29932993
return true;
29942994
}
29952995

2996+
bool CodeGenPatternMatch::MatchCanonicalizeInstruction(llvm::Instruction& I)
2997+
{
2998+
struct CanonicalizeInstPattern : Pattern
2999+
{
3000+
CanonicalizeInstPattern(llvm::Instruction* pInst, bool isNeeded) : m_pInst(pInst), m_IsNeeded(isNeeded) {}
3001+
3002+
llvm::Instruction* m_pInst;
3003+
bool m_IsNeeded;
3004+
3005+
virtual void Emit(EmitPass* pass, const DstModifier& modifier)
3006+
{
3007+
assert(modifier.sat == false && modifier.flag == nullptr);
3008+
if (m_IsNeeded)
3009+
{
3010+
pass->emitCanonicalize(m_pInst);
3011+
}
3012+
}
3013+
};
3014+
3015+
assert(I.getNumOperands() == 1);
3016+
bool isNeeded = true;
3017+
3018+
// FAdd, FSub, FMul, FDiv instructions flush subnormals to zero.
3019+
// However, mix mode and math instructions preserve subnormals.
3020+
// Other instructions also preserve subnormals.
3021+
if (llvm::BinaryOperator * pBianaryOperator = llvm::dyn_cast<llvm::BinaryOperator>(I.getOperand(0)))
3022+
{
3023+
switch (pBianaryOperator->getOpcode())
3024+
{
3025+
case llvm::BinaryOperator::BinaryOps::FAdd:
3026+
case llvm::BinaryOperator::BinaryOps::FMul:
3027+
case llvm::BinaryOperator::BinaryOps::FSub:
3028+
case llvm::BinaryOperator::BinaryOps::FDiv:
3029+
isNeeded = false;
3030+
default:
3031+
break;
3032+
}
3033+
}
3034+
3035+
CanonicalizeInstPattern* pattern = new (m_allocator) CanonicalizeInstPattern(&I, isNeeded);
3036+
MarkAsSource(I.getOperand(0));
3037+
3038+
AddPattern(pattern);
3039+
return true;
3040+
}
3041+
29963042
bool CodeGenPatternMatch::MatchBranch(llvm::BranchInst& I)
29973043
{
29983044
struct CondBrInstPattern : Pattern

IGC/Compiler/CISACodeGen/PatternMatchPass.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ namespace IGC
196196
bool MatchCmpSext(llvm::Instruction& I);
197197
bool MatchModifier(llvm::Instruction& I, bool SupportSrc0Mod = true);
198198
bool MatchSingleInstruction(llvm::Instruction& I);
199+
bool MatchCanonicalizeInstruction(llvm::Instruction& I);
199200
bool MatchBranch(llvm::BranchInst& I);
200201
bool MatchShuffleBroadCast(llvm::GenIntrinsicInst& I);
201202
bool MatchWaveShuffleIndex(llvm::GenIntrinsicInst& I);

IGC/Compiler/CISACodeGen/opCode.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -129,6 +129,7 @@ DECLARE_OPCODE(FPExt, Instruction, llvm_fpext, true, false, false, false, false,
129129
DECLARE_OPCODE(GenISA_f32tof16_rtz, GenISAIntrinsic, llvm_f32tof16_rtz, true, false, false, false, true, false, false)
130130
DECLARE_OPCODE(fabs, Intrinsic, llvm_fabs, false, false, true, false, true, false, false)
131131
DECLARE_OPCODE(GenISA_fsat, GenISAIntrinsic, llvm_fsat, true, false, true, true, true, false, false)
132+
DECLARE_OPCODE(canonicalize, Intrinsic, llvm_canonicalize, true, true, true, true, false, false, false)
132133

133134
// GS Intrinsics
134135
DECLARE_OPCODE(GenISA_OUTPUTGS, GenISAIntrinsic, llvm_output_gs, false, false, false, false, false, false, false)

IGC/Compiler/CustomSafeOptPass.cpp

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2351,6 +2351,17 @@ Constant* IGCConstProp::replaceShaderConstant(LoadInst* inst)
23512351
return nullptr;
23522352
}
23532353

2354+
llvm::Constant* IGC::IGCConstantFolder::CreateCanonicalize(llvm::Constant* C0, bool flushDenorms /*= true*/) const
2355+
{
2356+
assert(llvm::isa<ConstantFP>(C0));
2357+
auto APF = llvm::cast<ConstantFP>(C0)->getValueAPF();
2358+
if (flushDenorms && APF.isDenormal())
2359+
{
2360+
APF = APFloat::getZero(APF.getSemantics(), APF.isNegative());
2361+
}
2362+
return ConstantFP::get(C0->getContext(), APF);
2363+
}
2364+
23542365
Constant* IGCConstProp::ConstantFoldCallInstruction(CallInst* inst)
23552366
{
23562367
Constant* C = nullptr;
@@ -2453,6 +2464,22 @@ Constant* IGCConstProp::ConstantFoldCallInstruction(CallInst* inst)
24532464
C = ConstantFP::get(inst->getContext(), minnum(One, maxnum(zero, A)));
24542465
}
24552466
}
2467+
break;
2468+
case llvm_canonicalize:
2469+
{
2470+
// If the instruction should be emitted anyway, then remove the condition.
2471+
// Please, be aware of the fact that clients can understand the term canonical FP value in other way.
2472+
if (C0)
2473+
{
2474+
IGCConstantFolder constantFolder;
2475+
CodeGenContext* pCodeGenContext = getAnalysis<CodeGenContextWrapper>().getCodeGenContext();
2476+
bool flushVal = pCodeGenContext->m_floatDenormMode16 == ::IGC::FLOAT_DENORM_FLUSH_TO_ZERO && inst->getType()->isHalfTy();
2477+
flushVal = flushVal || (pCodeGenContext->m_floatDenormMode32 == ::IGC::FLOAT_DENORM_FLUSH_TO_ZERO && inst->getType()->isFloatTy());
2478+
flushVal = flushVal || (pCodeGenContext->m_floatDenormMode64 == ::IGC::FLOAT_DENORM_FLUSH_TO_ZERO && inst->getType()->isDoubleTy());
2479+
C = constantFolder.CreateCanonicalize(C0, flushVal);
2480+
}
2481+
}
2482+
break;
24562483
default:
24572484
break;
24582485
}
@@ -2934,7 +2961,6 @@ bool IGCConstProp::runOnFunction(Function& F)
29342961
return Changed;
29352962
}
29362963

2937-
29382964
namespace {
29392965

29402966
class IGCIndirectICBPropagaion : public FunctionPass
@@ -2945,7 +2971,7 @@ namespace {
29452971
{
29462972
initializeIGCIndirectICBPropagaionPass(*PassRegistry::getPassRegistry());
29472973
}
2948-
virtual llvm::StringRef getPassName() const { return "Indirect ICB Propagaion"; }
2974+
virtual llvm::StringRef getPassName() const { return "Indirect ICB Propagation"; }
29492975
virtual bool runOnFunction(Function& F);
29502976
virtual void getAnalysisUsage(llvm::AnalysisUsage& AU) const
29512977
{
@@ -4186,5 +4212,4 @@ bool LogicalAndToBranch::runOnFunction(Function& F)
41864212
}
41874213

41884214
return changed;
4189-
}
4190-
4215+
}

IGC/Compiler/CustomSafeOptPass.hpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
3333
#include <llvm/Analysis/TargetLibraryInfo.h>
3434
#include <llvm/Analysis/LoopPass.h>
3535
#include <llvm/IR/Instructions.h>
36+
#include <llvm/IR/ConstantFolder.h>
3637
#include "common/LLVMWarningsPop.hpp"
3738

3839
namespace llvm
@@ -201,6 +202,16 @@ namespace IGC
201202
void visitSelectInst(llvm::SelectInst& I);
202203
};
203204

205+
class IGCConstantFolder : public llvm::ConstantFolder
206+
{
207+
public:
208+
IGCConstantFolder() :
209+
ConstantFolder()
210+
{}
211+
212+
llvm::Constant* CreateCanonicalize(llvm::Constant* C0, bool flushDenorms = true) const;
213+
};
214+
204215
class IGCConstProp : public llvm::FunctionPass
205216
{
206217
public:
@@ -225,13 +236,14 @@ namespace IGC
225236
// specialized const-prop with shader-const replacement
226237
return "const-prop with shader-const replacement";
227238
}
239+
228240
private:
229241
llvm::Module* module;
230242
llvm::Constant* ReplaceFromDynConstants(unsigned bufId, unsigned eltId, unsigned int size_in_bytes, llvm::LoadInst* inst);
231243
llvm::Constant* replaceShaderConstant(llvm::LoadInst* inst);
232-
llvm::Constant* ConstantFoldCallInstruction(llvm::CallInst* inst);
233244
llvm::Constant* ConstantFoldCmpInst(llvm::CmpInst* inst);
234245
llvm::Constant* ConstantFoldExtractElement(llvm::ExtractElementInst* inst);
246+
llvm::Constant* ConstantFoldCallInstruction(llvm::CallInst* inst);
235247
bool simplifyAdd(llvm::BinaryOperator* BO);
236248
bool simplifyGEP(llvm::GetElementPtrInst* GEP);
237249
bool m_enableMathConstProp;

IGC/Compiler/IGC_IR_spec.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ IGC_IR_LLVM_INTRINSIC(assume)
9797
IGC_IR_LLVM_INTRINSIC(bswap)
9898
IGC_IR_LLVM_INTRINSIC(maxnum)
9999
IGC_IR_LLVM_INTRINSIC(minnum)
100+
IGC_IR_LLVM_INTRINSIC(canonicalize)
100101
#if LLVM_VERSION_MAJOR >= 8
101102
IGC_IR_LLVM_INTRINSIC(fshl)
102103
IGC_IR_LLVM_INTRINSIC(fshr)

IGC/common/MDFrameWork.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,7 @@ namespace IGC
361361
// When true compiler can assume that resources bound to two different
362362
// bindings do not alias.
363363
bool statefullResourcesNotAliased = false;
364+
bool disableMixMode = false;
364365

365366
unsigned int privateMemoryPerWI = 0;
366367
std::array<uint64_t, NUM_SHADER_RESOURCE_VIEW_SIZE> m_ShaderResourceViewMcsMask{};

0 commit comments

Comments
 (0)