@@ -954,7 +954,7 @@ namespace IGC
954
954
switch (I.getOpcode ())
955
955
{
956
956
case Instruction::FSub:
957
- match = MatchFloor (I) ||
957
+ match = MatchFloor (I) ||
958
958
MatchFrc (I) ||
959
959
MatchLrp (I) ||
960
960
MatchPredAdd (I) ||
@@ -999,7 +999,7 @@ namespace IGC
999
999
MatchModifier (I);
1000
1000
break ;
1001
1001
case Instruction::FAdd:
1002
- match =
1002
+ match =
1003
1003
MatchLrp (I) ||
1004
1004
MatchPredAdd (I) ||
1005
1005
MatchMad (I) ||
@@ -1220,6 +1220,9 @@ namespace IGC
1220
1220
case Intrinsic::fshr:
1221
1221
match = MatchFunnelShiftRotate (I);
1222
1222
break ;
1223
+ case Intrinsic::canonicalize:
1224
+ match = MatchCanonicalizeInstruction (I);
1225
+ break ;
1223
1226
default :
1224
1227
match = MatchSingleInstruction (I);
1225
1228
// no pattern for the rest of the intrinsics
@@ -1626,9 +1629,9 @@ namespace IGC
1626
1629
}
1627
1630
return found;
1628
1631
}
1629
-
1632
+
1630
1633
/*
1631
- below pass handles x - frac(x) = floor(x) pattern. Refer below :
1634
+ below pass handles x - frac(x) = floor(x) pattern. Refer below :
1632
1635
1633
1636
frc (8|M0) r20.0<1>:f r19.0<8;8,1>:f {Compacted, @1}
1634
1637
add (8|M0) (ge)f0.1 r19.0<1>:f r19.0<8;8,1>:f -r20.0<8;8,1>:f {@1}
@@ -3101,43 +3104,120 @@ namespace IGC
3101
3104
{
3102
3105
struct CanonicalizeInstPattern : Pattern
3103
3106
{
3104
- CanonicalizeInstPattern (llvm::Instruction* pInst, bool isNeeded ) : m_pInst(pInst), m_IsNeeded(isNeeded ) {}
3107
+ CanonicalizeInstPattern (llvm::Instruction* pInst) : m_pInst(pInst) {}
3105
3108
3106
3109
llvm::Instruction* m_pInst;
3107
- bool m_IsNeeded ;
3110
+ Pattern* m_pPattern = nullptr ;
3108
3111
3109
3112
virtual void Emit (EmitPass* pass, const DstModifier& modifier)
3110
3113
{
3111
- IGC_ASSERT (modifier.sat == false && modifier.flag == nullptr );
3112
- if (m_IsNeeded)
3114
+ if (m_pPattern)
3113
3115
{
3114
- pass->emitCanonicalize (m_pInst);
3116
+ m_pPattern->Emit (pass, modifier);
3117
+ }
3118
+ else
3119
+ {
3120
+ pass->emitCanonicalize (m_pInst, modifier);
3115
3121
}
3116
3122
}
3117
3123
};
3118
3124
3119
- IGC_ASSERT (I.getNumOperands () == 1 );
3120
- bool isNeeded = true ;
3121
3125
3122
3126
// FAdd, FSub, FMul, FDiv instructions flush subnormals to zero.
3123
3127
// However, mix mode and math instructions preserve subnormals.
3124
3128
// Other instructions also preserve subnormals.
3125
- if (llvm::BinaryOperator * pBianaryOperator = llvm::dyn_cast<llvm::BinaryOperator>(I.getOperand (0 )))
3129
+ // FSat intrinsic instruction can be emitted i.e. as FAdd so such an
3130
+ // instruction should be inspected recursively.
3131
+ std::function<bool (llvm::Value*)> DetermineIfMixMode;
3132
+ DetermineIfMixMode = [&DetermineIfMixMode, this ](llvm::Value* operand) -> bool
3126
3133
{
3127
- switch (pBianaryOperator->getOpcode ())
3134
+ bool isMixModePossible = false ;
3135
+ if (m_Platform.supportMixMode ())
3128
3136
{
3129
- case llvm::BinaryOperator::BinaryOps::FAdd:
3130
- case llvm::BinaryOperator::BinaryOps::FMul:
3131
- case llvm::BinaryOperator::BinaryOps::FSub:
3132
- case llvm::BinaryOperator::BinaryOps::FDiv:
3133
- isNeeded = false ;
3134
- default :
3135
- break ;
3137
+ if (llvm::BinaryOperator* pBianaryOperator = llvm::dyn_cast<llvm::BinaryOperator>(operand))
3138
+ {
3139
+ // the switch instruction is executed to break the recursion if it is unneeded.
3140
+ // The cause for this recursion is a possibility of constructing mad instructions.
3141
+ switch (pBianaryOperator->getOpcode ())
3142
+ {
3143
+ case llvm::BinaryOperator::BinaryOps::FAdd:
3144
+ case llvm::BinaryOperator::BinaryOps::FMul:
3145
+ case llvm::BinaryOperator::BinaryOps::FSub:
3146
+ isMixModePossible = pBianaryOperator->getType ()->isDoubleTy () == false &&
3147
+ (DetermineIfMixMode (pBianaryOperator->getOperand (0 )) || DetermineIfMixMode (pBianaryOperator->getOperand (1 )));
3148
+ break ;
3149
+ default :
3150
+ break ;
3151
+ }
3152
+ }
3153
+ else if (isa<FPTruncInst>(operand))
3154
+ {
3155
+ FPTruncInst* fptruncInst = llvm::cast<FPTruncInst>(operand);
3156
+ isMixModePossible = fptruncInst->getSrcTy ()->isDoubleTy () == false ;
3157
+ }
3158
+ else if (isa<FPExtInst>(operand))
3159
+ {
3160
+ FPExtInst* fpextInst = llvm::cast<FPExtInst>(operand);
3161
+ isMixModePossible = fpextInst->getDestTy ()->isDoubleTy () == false ;
3162
+ }
3136
3163
}
3137
- }
3164
+ return isMixModePossible;
3165
+ };
3138
3166
3139
- CanonicalizeInstPattern* pattern = new (m_allocator) CanonicalizeInstPattern (&I, isNeeded);
3140
- MarkAsSource (I.getOperand (0 ));
3167
+ std::function<bool (llvm::Value*)> DetermineIfNeeded;
3168
+ DetermineIfNeeded = [&DetermineIfNeeded, &DetermineIfMixMode](llvm::Value* operand) -> bool
3169
+ {
3170
+ bool isNeeded = true ;
3171
+ if (llvm::BinaryOperator* pBianaryOperator = llvm::dyn_cast<llvm::BinaryOperator>(operand))
3172
+ {
3173
+ // the switch instruction is to consider only the operations
3174
+ // which support flushing denorms to zero.
3175
+ switch (pBianaryOperator->getOpcode ())
3176
+ {
3177
+ case llvm::BinaryOperator::BinaryOps::FAdd:
3178
+ case llvm::BinaryOperator::BinaryOps::FMul:
3179
+ case llvm::BinaryOperator::BinaryOps::FSub:
3180
+ case llvm::BinaryOperator::BinaryOps::FDiv:
3181
+ isNeeded = DetermineIfMixMode (pBianaryOperator);
3182
+ break ;
3183
+ default :
3184
+ break ;
3185
+ }
3186
+ }
3187
+ else if (GenIntrinsicInst* intrin = dyn_cast<GenIntrinsicInst>(operand))
3188
+ {
3189
+ switch (intrin->getIntrinsicID ())
3190
+ {
3191
+ case GenISAIntrinsic::GenISA_fsat:
3192
+ isNeeded = DetermineIfNeeded (intrin->getOperand (0 ));
3193
+ break ;
3194
+ default :
3195
+ break ;
3196
+ }
3197
+ }
3198
+ else if (IntrinsicInst* intrin = dyn_cast<IntrinsicInst>(operand))
3199
+ {
3200
+ switch (intrin->getIntrinsicID ())
3201
+ {
3202
+ case Intrinsic::canonicalize:
3203
+ isNeeded = DetermineIfNeeded (intrin->getOperand (0 ));
3204
+ break ;
3205
+ default :
3206
+ break ;
3207
+ }
3208
+ }
3209
+ return isNeeded;
3210
+ };
3211
+
3212
+ CanonicalizeInstPattern* pattern = new (m_allocator) CanonicalizeInstPattern (&I);
3213
+ if (DetermineIfNeeded (I.getOperand (0 )))
3214
+ {
3215
+ MarkAsSource (I.getOperand (0 ));
3216
+ }
3217
+ else
3218
+ {
3219
+ pattern->m_pPattern = Match (*llvm::cast<llvm::Instruction>(I.getOperand (0 )));
3220
+ }
3141
3221
3142
3222
AddPattern (pattern);
3143
3223
return true ;
0 commit comments