Skip to content

Commit 6931b3b

Browse files
JIT: Fix over-shifting logic when constant-folding AdvSimd.ShiftRight* and AdvSimd.ShiftLeft* (#105847)
1 parent c2d0589 commit 6931b3b

File tree

7 files changed

+335
-23
lines changed

7 files changed

+335
-23
lines changed

src/coreclr/jit/hwintrinsic.cpp

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,12 +1597,15 @@ bool Compiler::CheckHWIntrinsicImmRange(NamedIntrinsic intrinsic,
15971597
#ifdef TARGET_ARM64
15981598
switch (intrinsic)
15991599
{
1600+
case NI_AdvSimd_ShiftLeftLogical:
1601+
case NI_AdvSimd_ShiftLeftLogicalScalar:
16001602
case NI_AdvSimd_ShiftRightLogical:
1603+
case NI_AdvSimd_ShiftRightLogicalScalar:
1604+
case NI_AdvSimd_ShiftRightArithmetic:
1605+
case NI_AdvSimd_ShiftRightArithmeticScalar:
16011606
*useFallback = true;
16021607
break;
16031608

1604-
// TODO: Implement more AdvSimd fallbacks in Compiler::impNonConstFallback
1605-
16061609
default:
16071610
assert(*useFallback == false);
16081611
break;
@@ -1633,7 +1636,7 @@ bool Compiler::CheckHWIntrinsicImmRange(NamedIntrinsic intrinsic,
16331636
}
16341637
}
16351638
else
1636-
#endif // TARGET_XARCH
1639+
#endif // TARGET_X86
16371640
{
16381641
*useFallback = true;
16391642
return false;

src/coreclr/jit/hwintrinsicarm64.cpp

Lines changed: 44 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -564,20 +564,59 @@ void HWIntrinsicInfo::lookupImmBounds(
564564
//
565565
GenTree* Compiler::impNonConstFallback(NamedIntrinsic intrinsic, var_types simdType, CorInfoType simdBaseJitType)
566566
{
567+
bool isRightShift = true;
568+
567569
switch (intrinsic)
568570
{
571+
case NI_AdvSimd_ShiftLeftLogical:
572+
case NI_AdvSimd_ShiftLeftLogicalScalar:
573+
isRightShift = false;
574+
FALLTHROUGH;
575+
569576
case NI_AdvSimd_ShiftRightLogical:
577+
case NI_AdvSimd_ShiftRightLogicalScalar:
578+
case NI_AdvSimd_ShiftRightArithmetic:
579+
case NI_AdvSimd_ShiftRightArithmeticScalar:
570580
{
571-
// AdvSimd.ShiftRightLogical be replaced with AdvSimd.ShiftLogical, which takes op2 in a simd register
581+
// AdvSimd.ShiftLeft* and AdvSimd.ShiftRight* can be replaced with AdvSimd.Shift*, which takes op2 in a simd
582+
// register
572583

573584
GenTree* op2 = impPopStack().val;
574585
GenTree* op1 = impSIMDPopStack();
575586

576587
// AdvSimd.ShiftLogical does right-shifts with negative immediates, hence the negation
577-
GenTree* tmpOp =
578-
gtNewSimdCreateBroadcastNode(simdType, gtNewOperNode(GT_NEG, genActualType(op2->TypeGet()), op2),
579-
simdBaseJitType, genTypeSize(simdType));
580-
return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, NI_AdvSimd_ShiftLogical, simdBaseJitType,
588+
if (isRightShift)
589+
{
590+
op2 = gtNewOperNode(GT_NEG, genActualType(op2->TypeGet()), op2);
591+
}
592+
593+
NamedIntrinsic fallbackIntrinsic;
594+
switch (intrinsic)
595+
{
596+
case NI_AdvSimd_ShiftLeftLogical:
597+
case NI_AdvSimd_ShiftRightLogical:
598+
fallbackIntrinsic = NI_AdvSimd_ShiftLogical;
599+
break;
600+
601+
case NI_AdvSimd_ShiftLeftLogicalScalar:
602+
case NI_AdvSimd_ShiftRightLogicalScalar:
603+
fallbackIntrinsic = NI_AdvSimd_ShiftLogicalScalar;
604+
break;
605+
606+
case NI_AdvSimd_ShiftRightArithmetic:
607+
fallbackIntrinsic = NI_AdvSimd_ShiftArithmetic;
608+
break;
609+
610+
case NI_AdvSimd_ShiftRightArithmeticScalar:
611+
fallbackIntrinsic = NI_AdvSimd_ShiftArithmeticScalar;
612+
break;
613+
614+
default:
615+
unreached();
616+
}
617+
618+
GenTree* tmpOp = gtNewSimdCreateBroadcastNode(simdType, op2, simdBaseJitType, genTypeSize(simdType));
619+
return gtNewSimdHWIntrinsicNode(simdType, op1, tmpOp, fallbackIntrinsic, simdBaseJitType,
581620
genTypeSize(simdType));
582621
}
583622

src/coreclr/jit/hwintrinsiclistarm64.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -433,12 +433,12 @@ HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticSaturateScalar,
433433
HARDWARE_INTRINSIC(AdvSimd, ShiftArithmeticScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sshl, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_SIMDScalar)
434434
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftAndInsert, -1, 3, {INS_sli, INS_sli, INS_sli, INS_sli, INS_sli, INS_sli, INS_sli, INS_sli, INS_sli, INS_sli}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
435435
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftAndInsertScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sli, INS_sli, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar)
436-
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogical, -1, 2, {INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand)
436+
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogical, -1, 2, {INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_shl, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_NoJmpTableIMM)
437437
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturate, -1, 2, {INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_sqshl, INS_uqshl, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand)
438438
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturateScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqshl, INS_uqshl, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
439439
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturateUnsigned, -1, 2, {INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_sqshlu, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand)
440440
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalSaturateUnsignedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sqshlu, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
441-
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_shl, INS_shl, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
441+
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_shl, INS_shl, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar|HW_Flag_NoJmpTableIMM)
442442
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalWideningLower, 8, 2, {INS_sshll, INS_ushll, INS_sshll, INS_ushll, INS_sshll, INS_ushll, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand)
443443
HARDWARE_INTRINSIC(AdvSimd, ShiftLeftLogicalWideningUpper, 16, 2, {INS_sshll2, INS_ushll2, INS_sshll2, INS_ushll2, INS_sshll2, INS_ushll2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftLeftByImmediate, HW_Flag_BaseTypeFromFirstArg|HW_Flag_HasImmediateOperand)
444444
HARDWARE_INTRINSIC(AdvSimd, ShiftLogical, -1, 2, {INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_ushl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_NoFlag)
@@ -451,7 +451,7 @@ HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalSaturateScalar,
451451
HARDWARE_INTRINSIC(AdvSimd, ShiftLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ushl, INS_ushl, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_SIMDScalar)
452452
HARDWARE_INTRINSIC(AdvSimd, ShiftRightAndInsert, -1, 3, {INS_sri, INS_sri, INS_sri, INS_sri, INS_sri, INS_sri, INS_sri, INS_sri, INS_sri, INS_sri}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
453453
HARDWARE_INTRINSIC(AdvSimd, ShiftRightAndInsertScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sri, INS_sri, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar)
454-
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmetic, -1, 2, {INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand)
454+
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmetic, -1, 2, {INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_sshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_NoJmpTableIMM)
455455
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticAdd, -1, 3, {INS_ssra, INS_invalid, INS_ssra, INS_invalid, INS_ssra, INS_invalid, INS_ssra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
456456
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ssra, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar)
457457
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticNarrowingSaturateLower, 8, 2, {INS_sqshrn, INS_invalid, INS_sqshrn, INS_invalid, INS_sqshrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand)
@@ -466,8 +466,8 @@ HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateUn
466466
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateUnsignedUpper, 16, 3, {INS_invalid, INS_sqrshrun2, INS_invalid, INS_sqrshrun2, INS_invalid, INS_sqrshrun2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
467467
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedNarrowingSaturateUpper, 16, 3, {INS_sqrshrn2, INS_invalid, INS_sqrshrn2, INS_invalid, INS_sqrshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
468468
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticRoundedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_srshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
469-
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
470-
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogical, -1, 2, {INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand)
469+
HARDWARE_INTRINSIC(AdvSimd, ShiftRightArithmeticScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_sshr, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar|HW_Flag_NoJmpTableIMM)
470+
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogical, -1, 2, {INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_ushr, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_NoJmpTableIMM)
471471
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalAdd, -1, 3, {INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_usra, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
472472
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalAddScalar, 8, 3, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_usra, INS_usra, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics|HW_Flag_SIMDScalar)
473473
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalNarrowingLower, 8, 2, {INS_shrn, INS_shrn, INS_shrn, INS_shrn, INS_shrn, INS_shrn, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand)
@@ -482,7 +482,7 @@ HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingSaturateLower
482482
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingSaturateUpper, 16, 3, {INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_uqrshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
483483
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedNarrowingUpper, 16, 3, {INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_rshrn2, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_HasRMWSemantics)
484484
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalRoundedScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_urshr, INS_urshr, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
485-
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ushr, INS_ushr, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar)
485+
HARDWARE_INTRINSIC(AdvSimd, ShiftRightLogicalScalar, 8, 2, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_ushr, INS_ushr, INS_invalid, INS_invalid}, HW_Category_ShiftRightByImmediate, HW_Flag_HasImmediateOperand|HW_Flag_SIMDScalar|HW_Flag_NoJmpTableIMM)
486486
HARDWARE_INTRINSIC(AdvSimd, SignExtendWideningLower, 8, 1, {INS_sxtl, INS_invalid, INS_sxtl, INS_invalid, INS_sxtl, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg)
487487
HARDWARE_INTRINSIC(AdvSimd, SignExtendWideningUpper, 16, 1, {INS_sxtl2, INS_invalid, INS_sxtl2, INS_invalid, INS_sxtl2, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid}, HW_Category_SIMD, HW_Flag_BaseTypeFromFirstArg)
488488
HARDWARE_INTRINSIC(AdvSimd, SqrtScalar, 8, 1, {INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_invalid, INS_fsqrt, INS_fsqrt}, HW_Category_SIMD, HW_Flag_SIMDScalar)

0 commit comments

Comments
 (0)