[Arm64] Simplify logic for RMW hardware intrinsics (#34668)
authorEgor Chesakov <Egor.Chesakov@microsoft.com>
Thu, 9 Apr 2020 01:50:28 +0000 (18:50 -0700)
committerGitHub <noreply@github.com>
Thu, 9 Apr 2020 01:50:28 +0000 (18:50 -0700)
* Make HW_Flag_NoRMWSemantics Intel-architecture specific and add HW_Flag_HasRMWSemantics on Arm64 in hwintrinsic.h

* Mark RMW intrinsics with the new flag in hwintrinsiclistarm64.h

* setTgtPref should be also enabled under FEATURE_HW_INTRINSICS - to allow preferential targetReg allocation on Arm64 in lsrabuild.cpp

* Redo LinearScan::BuildHWIntrinsic in lsraarm64.cpp

* Use HWIntrinsicInfo::HasRMWSemantics in GenTree::isRMWHWIntrinsic in gentree.cpp

* Remove SpecialCodeGen for ExtractAndNarrowHigh, Decrypt and Encrypt and add RMW specific codegen in hwintrinsiccodegenarm64.cpp hwintrinsiclistarm64.h

src/coreclr/src/jit/gentree.cpp
src/coreclr/src/jit/hwintrinsic.h
src/coreclr/src/jit/hwintrinsiccodegenarm64.cpp
src/coreclr/src/jit/hwintrinsiclistarm64.h
src/coreclr/src/jit/lsraarm64.cpp
src/coreclr/src/jit/lsrabuild.cpp

index 0eaf9cf..f5b72fc 100644 (file)
@@ -18423,7 +18423,7 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp)
     assert(gtOper == GT_HWINTRINSIC);
     assert(comp != nullptr);
 
-#ifdef TARGET_XARCH
+#if defined(TARGET_XARCH)
     if (!comp->canUseVexEncoding())
     {
         return HWIntrinsicInfo::HasRMWSemantics(AsHWIntrinsic()->gtHWIntrinsicId);
@@ -18454,9 +18454,11 @@ bool GenTree::isRMWHWIntrinsic(Compiler* comp)
             return false;
         }
     }
+#elif defined(TARGET_ARM64)
+    return HWIntrinsicInfo::HasRMWSemantics(AsHWIntrinsic()->gtHWIntrinsicId);
 #else
     return false;
-#endif // TARGET_XARCH
+#endif
 }
 
 GenTreeHWIntrinsic* Compiler::gtNewSimdHWIntrinsicNode(var_types      type,
index b80dce7..488e77f 100644 (file)
@@ -96,9 +96,16 @@ enum HWIntrinsicFlag : unsigned int
     // but may be table-driven in the front-end
     HW_Flag_SpecialCodeGen = 0x2000,
 
+#if defined(TARGET_XARCH)
     // No Read/Modify/Write Semantics
     // the intrinsic doesn't have read/modify/write semantics in two/three-operand form.
     HW_Flag_NoRMWSemantics = 0x4000,
+#elif defined(TARGET_ARM64)
+    // The intrinsic has read/modify/write semantics in multiple-operands form.
+    HW_Flag_HasRMWSemantics = 0x4000,
+#else
+#error Unsupported platform
+#endif
 
     // Special import
     // the intrinsics need special rules in importer,
@@ -292,7 +299,13 @@ struct HWIntrinsicInfo
     static bool HasRMWSemantics(NamedIntrinsic id)
     {
         HWIntrinsicFlag flags = lookupFlags(id);
+#if defined(TARGET_XARCH)
         return (flags & HW_Flag_NoRMWSemantics) == 0;
+#elif defined(TARGET_ARM64)
+        return (flags & HW_Flag_HasRMWSemantics) != 0;
+#else
+#error Unsupported platform
+#endif
     }
 
     static bool HasSpecialImport(NamedIntrinsic id)
index 8d74e9c..61139e2 100644 (file)
@@ -163,6 +163,8 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
         }
     }
 
+    const bool isRMW = node->isRMWHWIntrinsic(compiler);
+
     genConsumeHWIntrinsicOperands(node);
 
     if (intrin.IsTableDriven())
@@ -177,10 +179,27 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
                 break;
 
             case 2:
-                GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt);
+                if (isRMW)
+                {
+                    assert(targetReg != op2Reg);
+
+                    if (targetReg != op1Reg)
+                    {
+                        GetEmitter()->emitIns_R_R(INS_mov, emitSize, targetReg, op1Reg);
+                    }
+                    GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
+                }
+                else
+                {
+                    GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op1Reg, op2Reg, opt);
+                }
                 break;
 
             case 3:
+                assert(isRMW);
+                assert(targetReg != op2Reg);
+                assert(targetReg != op3Reg);
+
                 if (targetReg != op1Reg)
                 {
                     GetEmitter()->emitIns_R_R(INS_mov, emitSize, targetReg, op1Reg);
@@ -240,6 +259,10 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
         switch (intrin.id)
         {
             case NI_AdvSimd_BitwiseSelect:
+                // Even though BitwiseSelect is an RMW intrinsic per se, we don't want to mark it as such
+                // since we can handle all possible allocation decisions for targetReg.
+                assert(!isRMW);
+
                 if (targetReg == op1Reg)
                 {
                     GetEmitter()->emitIns_R_R_R(INS_bsl, emitSize, targetReg, op2Reg, op3Reg, opt);
@@ -259,15 +282,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
                 }
                 break;
 
-            case NI_Aes_Decrypt:
-            case NI_Aes_Encrypt:
-                if (targetReg != op1Reg)
-                {
-                    GetEmitter()->emitIns_R_R(INS_mov, emitSize, targetReg, op1Reg);
-                }
-                GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
-                break;
-
             case NI_Crc32_ComputeCrc32:
             case NI_Crc32_ComputeCrc32C:
             case NI_Crc32_Arm64_ComputeCrc32:
@@ -293,14 +307,6 @@ void CodeGen::genHWIntrinsic(GenTreeHWIntrinsic* node)
                 GetEmitter()->emitIns_R_R_R(ins, emitSize, targetReg, op2Reg, op1Reg, opt);
                 break;
 
-            case NI_AdvSimd_ExtractAndNarrowHigh:
-                if (targetReg != op1Reg)
-                {
-                    GetEmitter()->emitIns_R_R(INS_mov, emitSize, targetReg, op1Reg);
-                }
-                GetEmitter()->emitIns_R_R(ins, emitSize, targetReg, op2Reg, opt);
-                break;
-
             case NI_AdvSimd_FusedMultiplyAddScalar:
             case NI_AdvSimd_FusedMultiplyAddNegatedScalar:
             case NI_AdvSimd_FusedMultiplySubtractNegatedScalar:
index 84796ca..6a82bad 100644 (file)
@@ -55,7 +55,7 @@ HARDWARE_INTRINSIC(AdvSimd,         AbsoluteCompareGreaterThanOrEqual,         -
 HARDWARE_INTRINSIC(AdvSimd,         AbsoluteCompareLessThan,                   -1,              -1,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_facgt,          INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_SpecialCodeGen)
 HARDWARE_INTRINSIC(AdvSimd,         AbsoluteCompareLessThanOrEqual,            -1,              -1,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_facge,          INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_SpecialCodeGen)
 HARDWARE_INTRINSIC(AdvSimd,         AbsoluteDifference,                        -1,              -1,           2,     {INS_sabd,              INS_uabd,           INS_sabd,           INS_uabd,           INS_sabd,           INS_uabd,           INS_invalid,        INS_invalid,        INS_fabd,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_BaseTypeFromFirstArg)
-HARDWARE_INTRINSIC(AdvSimd,         AbsoluteDifferenceAdd,                     -1,              -1,           3,     {INS_saba,              INS_uaba,           INS_saba,           INS_uaba,           INS_saba,           INS_uaba,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
+HARDWARE_INTRINSIC(AdvSimd,         AbsoluteDifferenceAdd,                     -1,              -1,           3,     {INS_saba,              INS_uaba,           INS_saba,           INS_uaba,           INS_saba,           INS_uaba,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(AdvSimd,         Add,                                       -1,              -1,           2,     {INS_add,               INS_add,            INS_add,            INS_add,            INS_add,            INS_add,            INS_add,            INS_add,            INS_fadd,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_Commutative|HW_Flag_UnfixedSIMDSize)
 HARDWARE_INTRINSIC(AdvSimd,         AddPairwise,                               -1,               8,           2,     {INS_addp,              INS_addp,           INS_addp,           INS_addp,           INS_addp,           INS_addp,           INS_invalid,        INS_invalid,        INS_faddp,          INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
 HARDWARE_INTRINSIC(AdvSimd,         AddScalar,                                 -1,               8,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_add,            INS_add,            INS_fadd,           INS_fadd},              HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_Commutative)
@@ -70,17 +70,17 @@ HARDWARE_INTRINSIC(AdvSimd,         CompareLessThanOrEqual,                    -
 HARDWARE_INTRINSIC(AdvSimd,         CompareTest,                               -1,              -1,           2,     {INS_cmtst,             INS_cmtst,          INS_cmtst,          INS_cmtst,          INS_cmtst,          INS_cmtst,          INS_invalid,        INS_invalid,        INS_cmtst,          INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_Commutative|HW_Flag_UnfixedSIMDSize)
 HARDWARE_INTRINSIC(AdvSimd,         DivideScalar,                              -1,               8,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fdiv,           INS_fdiv},              HW_Category_SIMDScalar,             HW_Flag_NoContainment)
 HARDWARE_INTRINSIC(AdvSimd,         ExtractAndNarrowLow,                       -1,               8,           1,     {INS_xtn,               INS_xtn,            INS_xtn,            INS_xtn,            INS_xtn,            INS_xtn,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(AdvSimd,         ExtractAndNarrowHigh,                      -1,              16,           2,     {INS_xtn2,              INS_xtn2,           INS_xtn2,           INS_xtn2,           INS_xtn2,           INS_xtn2,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
-HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplyAdd,                          -1,              -1,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmla,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
+HARDWARE_INTRINSIC(AdvSimd,         ExtractAndNarrowHigh,                      -1,              16,           2,     {INS_xtn2,              INS_xtn2,           INS_xtn2,           INS_xtn2,           INS_xtn2,           INS_xtn2,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplyAdd,                          -1,              -1,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmla,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplyAddScalar,                    -1,               8,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmadd,          INS_fmadd},             HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
 HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplyAddNegatedScalar,             -1,               8,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fnmadd,         INS_fnmadd},            HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
-HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplySubtract,                     -1,              -1,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmls,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
+HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplySubtract,                     -1,              -1,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmls,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplySubtractScalar,               -1,               8,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmsub,          INS_fmsub},             HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
 HARDWARE_INTRINSIC(AdvSimd,         FusedMultiplySubtractNegatedScalar,        -1,               8,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fnmsub,         INS_fnmsub},            HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
 HARDWARE_INTRINSIC(AdvSimd,         LeadingSignCount,                          -1,              -1,           1,     {INS_cls,               INS_invalid,        INS_cls,            INS_invalid,        INS_cls,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
 HARDWARE_INTRINSIC(AdvSimd,         LeadingZeroCount,                          -1,              -1,           1,     {INS_clz,               INS_clz,            INS_clz,            INS_clz,            INS_clz,            INS_clz,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
-HARDWARE_INTRINSIC(AdvSimd,         LoadVector64,                              -1,               8,           1,     {INS_ld1,               INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1},               HW_Category_MemoryLoad,             HW_Flag_NoRMWSemantics)
-HARDWARE_INTRINSIC(AdvSimd,         LoadVector128,                             -1,              16,           1,     {INS_ld1,               INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1},               HW_Category_MemoryLoad,             HW_Flag_NoRMWSemantics)
+HARDWARE_INTRINSIC(AdvSimd,         LoadVector64,                              -1,               8,           1,     {INS_ld1,               INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1},               HW_Category_MemoryLoad,             HW_Flag_NoFlag)
+HARDWARE_INTRINSIC(AdvSimd,         LoadVector128,                             -1,              16,           1,     {INS_ld1,               INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1,            INS_ld1},               HW_Category_MemoryLoad,             HW_Flag_NoFlag)
 HARDWARE_INTRINSIC(AdvSimd,         Max,                                       -1,              -1,           2,     {INS_smax,              INS_umax,           INS_smax,           INS_umax,           INS_smax,           INS_umax,           INS_invalid,        INS_invalid,        INS_fmax,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd,         MaxNumber,                                 -1,              -1,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmaxnm,         INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd,         MaxNumberScalar,                           -1,               8,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmaxnm,         INS_fmaxnm},            HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_Commutative)
@@ -91,8 +91,8 @@ HARDWARE_INTRINSIC(AdvSimd,         MinNumberScalar,                           -
 HARDWARE_INTRINSIC(AdvSimd,         MinPairwise,                               -1,               8,           2,     {INS_sminp,             INS_uminp,          INS_sminp,          INS_uminp,          INS_sminp,          INS_uminp,          INS_invalid,        INS_invalid,        INS_fminp,          INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
 HARDWARE_INTRINSIC(AdvSimd,         Multiply,                                  -1,              -1,           2,     {INS_mul,               INS_mul,            INS_mul,            INS_mul,            INS_mul,            INS_mul,            INS_invalid,        INS_invalid,        INS_fmul,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd,         MultiplyScalar,                            -1,               8,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmul,           INS_fmul},              HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_Commutative)
-HARDWARE_INTRINSIC(AdvSimd,         MultiplyAdd,                               -1,              -1,           3,     {INS_mla,               INS_mla,            INS_mla,            INS_mla,            INS_mla,            INS_mla,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
-HARDWARE_INTRINSIC(AdvSimd,         MultiplySubtract,                          -1,              -1,           3,     {INS_mls,               INS_mls,            INS_mls,            INS_mls,            INS_mls,            INS_mls,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
+HARDWARE_INTRINSIC(AdvSimd,         MultiplyAdd,                               -1,              -1,           3,     {INS_mla,               INS_mla,            INS_mla,            INS_mla,            INS_mla,            INS_mla,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(AdvSimd,         MultiplySubtract,                          -1,              -1,           3,     {INS_mls,               INS_mls,            INS_mls,            INS_mls,            INS_mls,            INS_mls,            INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(AdvSimd,         Negate,                                    -1,              -1,           1,     {INS_neg,               INS_invalid,        INS_neg,            INS_invalid,        INS_neg,            INS_invalid,        INS_invalid,        INS_invalid,        INS_fneg,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
 HARDWARE_INTRINSIC(AdvSimd,         NegateScalar,                              -1,               8,           1,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fneg,           INS_fneg},              HW_Category_SIMDScalar,             HW_Flag_NoContainment)
 HARDWARE_INTRINSIC(AdvSimd,         Not,                                       -1,              -1,           1,     {INS_mvn,               INS_mvn,            INS_mvn,            INS_mvn,            INS_mvn,            INS_mvn,            INS_mvn,            INS_mvn,            INS_mvn,            INS_mvn},               HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
@@ -105,7 +105,7 @@ HARDWARE_INTRINSIC(AdvSimd,         ReciprocalSquareRootEstimate,              -
 HARDWARE_INTRINSIC(AdvSimd,         ReciprocalSquareRootStep,                  -1,              -1,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_frsqrts,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd,         ReciprocalStep,                            -1,              -1,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_frecps,         INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd,         SqrtScalar,                                -1,               8,           1,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fsqrt,          INS_fsqrt},             HW_Category_SIMDScalar,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(AdvSimd,         Store,                                     -1,              -1,           2,     {INS_st1,               INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1},               HW_Category_MemoryStore,            HW_Flag_NoRMWSemantics|HW_Flag_UnfixedSIMDSize|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg)
+HARDWARE_INTRINSIC(AdvSimd,         Store,                                     -1,              -1,           2,     {INS_st1,               INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1,            INS_st1},               HW_Category_MemoryStore,            HW_Flag_UnfixedSIMDSize|HW_Flag_SpecialCodeGen|HW_Flag_BaseTypeFromSecondArg)
 HARDWARE_INTRINSIC(AdvSimd,         Subtract,                                  -1,              -1,           2,     {INS_sub,               INS_sub,            INS_sub,            INS_sub,            INS_sub,            INS_sub,            INS_sub,            INS_sub,            INS_fsub,           INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
 HARDWARE_INTRINSIC(AdvSimd,         SubtractScalar,                            -1,               8,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sub,            INS_sub,            INS_fsub,           INS_fsub},              HW_Category_SIMDScalar,             HW_Flag_NoContainment)
 HARDWARE_INTRINSIC(AdvSimd,         Xor,                                       -1,              -1,           2,     {INS_eor,               INS_eor,            INS_eor,            INS_eor,            INS_eor,            INS_eor,            INS_eor,            INS_eor,            INS_eor,            INS_eor},               HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize|HW_Flag_Commutative)
@@ -144,8 +144,8 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64,   CompareLessThanScalar,                     -
 HARDWARE_INTRINSIC(AdvSimd_Arm64,   CompareTest,                               -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_cmtst,          INS_cmtst,          INS_invalid,        INS_cmtst},             HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd_Arm64,   CompareTestScalar,                         -1,               8,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_cmtst,          INS_cmtst,          INS_invalid,        INS_cmtst},             HW_Category_SIMDScalar,             HW_Flag_NoContainment|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd_Arm64,   Divide,                                    -1,              -1,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fdiv,           INS_fdiv},              HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_UnfixedSIMDSize)
-HARDWARE_INTRINSIC(AdvSimd_Arm64,   FusedMultiplyAdd,                          -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmla},              HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(AdvSimd_Arm64,   FusedMultiplySubtract,                     -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmls},              HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(AdvSimd_Arm64,   FusedMultiplyAdd,                          -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmla},              HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(AdvSimd_Arm64,   FusedMultiplySubtract,                     -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmls},              HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(AdvSimd_Arm64,   Max,                                       -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmax},              HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_Commutative)
 HARDWARE_INTRINSIC(AdvSimd_Arm64,   MaxAcross,                                 -1,              -1,           1,     {INS_smaxv,             INS_umaxv,          INS_smaxv,          INS_umaxv,          INS_smaxv,          INS_umaxv,          INS_invalid,        INS_invalid,        INS_fmaxv,          INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_BaseTypeFromFirstArg|HW_Flag_UnfixedSIMDSize)
 HARDWARE_INTRINSIC(AdvSimd_Arm64,   MaxNumber,                                 -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_fmaxnm},            HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_Commutative)
@@ -193,8 +193,8 @@ HARDWARE_INTRINSIC(AdvSimd_Arm64,   ZipLow,                                    -
 //                                                                                                                   {TYP_BYTE,              TYP_UBYTE,          TYP_SHORT,          TYP_USHORT,         TYP_INT,            TYP_UINT,           TYP_LONG,           TYP_ULONG,          TYP_FLOAT,          TYP_DOUBLE}
 // ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
 //  AES Intrinsics
-HARDWARE_INTRINSIC(Aes,             Decrypt,                                   -1,              16,           2,     {INS_invalid,           INS_aesd,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
-HARDWARE_INTRINSIC(Aes,             Encrypt,                                   -1,              16,           2,     {INS_invalid,           INS_aese,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_SpecialCodeGen)
+HARDWARE_INTRINSIC(Aes,             Decrypt,                                   -1,              16,           2,     {INS_invalid,           INS_aesd,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Aes,             Encrypt,                                   -1,              16,           2,     {INS_invalid,           INS_aese,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(Aes,             InverseMixColumns,                         -1,              16,           1,     {INS_invalid,           INS_aesimc,         INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
 HARDWARE_INTRINSIC(Aes,             MixColumns,                                -1,              16,           1,     {INS_invalid,           INS_aesmc,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
 
@@ -236,22 +236,22 @@ HARDWARE_INTRINSIC(Crc32_Arm64,     ComputeCrc32C,                             -
 //                                                                                                                   {TYP_BYTE,              TYP_UBYTE,          TYP_SHORT,          TYP_USHORT,         TYP_INT,            TYP_UINT,           TYP_LONG,           TYP_ULONG,          TYP_FLOAT,          TYP_DOUBLE}
 // ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
 //  SHA1 Intrinsics
-HARDWARE_INTRINSIC(Sha1,            HashUpdateChoose,                          -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1c,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha1,            HashUpdateMajority,                        -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1m,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha1,            HashUpdateParity,                          -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1p,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(Sha1,            HashUpdateChoose,                          -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1c,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sha1,            HashUpdateMajority,                        -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1m,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sha1,            HashUpdateParity,                          -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1p,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
 HARDWARE_INTRINSIC(Sha1,            FixedRotate,                               -1,               0,           1,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1h,          INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_Scalar,                 HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha1,            ScheduleUpdate0,                           -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1su0,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha1,            ScheduleUpdate1,                           -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1su1,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(Sha1,            ScheduleUpdate0,                           -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1su0,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sha1,            ScheduleUpdate1,                           -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha1su1,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
 
 // ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
 //                 ISA              Function name                            ival        SIMD size       NumArg                                                                                                     instructions                                                                                                     Category                            Flags
 //                                                                                                                   {TYP_BYTE,              TYP_UBYTE,          TYP_SHORT,          TYP_USHORT,         TYP_INT,            TYP_UINT,           TYP_LONG,           TYP_ULONG,          TYP_FLOAT,          TYP_DOUBLE}
 // ***************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************************
 //  SHA256 Intrinsics
-HARDWARE_INTRINSIC(Sha256,          HashUpdate1,                               -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256h,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha256,          HashUpdate2,                               -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256h2,       INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha256,          ScheduleUpdate0,                           -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256su0,      INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
-HARDWARE_INTRINSIC(Sha256,          ScheduleUpdate1,                           -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256su1,      INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment)
+HARDWARE_INTRINSIC(Sha256,          HashUpdate1,                               -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256h,        INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sha256,          HashUpdate2,                               -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256h2,       INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sha256,          ScheduleUpdate0,                           -1,              16,           2,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256su0,      INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
+HARDWARE_INTRINSIC(Sha256,          ScheduleUpdate1,                           -1,              16,           3,     {INS_invalid,           INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid,        INS_sha256su1,      INS_invalid,        INS_invalid,        INS_invalid,        INS_invalid},           HW_Category_SimpleSIMD,             HW_Flag_NoContainment|HW_Flag_HasRMWSemantics)
 
 #endif // FEATURE_HW_INTRINSIC
 
index 1b575d4..c7d06ea 100644 (file)
@@ -1053,8 +1053,6 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
 
         assert(lastOp != nullptr);
 
-        bool buildUses = true;
-
         if ((category == HW_Category_IMM) && !HWIntrinsicInfo::NoJmpTableImm(intrinsicId))
         {
             if (HWIntrinsicInfo::isImmOp(intrinsicId, lastOp) && !lastOp->isContainedIntOrIImmed())
@@ -1071,132 +1069,49 @@ int LinearScan::BuildHWIntrinsic(GenTreeHWIntrinsic* intrinsicTree)
 
         // Determine whether this is an RMW operation where op2+ must be marked delayFree so that it
         // is not allocated the same register as the target.
-        bool isRMW = intrinsicTree->isRMWHWIntrinsic(compiler);
+        const bool isRMW = intrinsicTree->isRMWHWIntrinsic(compiler);
+
+        bool tgtPrefOp1 = false;
 
-        // Create internal temps, and handle any other special requirements.
-        // Note that the default case for building uses will handle the RMW flag, but if the uses
-        // are built in the individual cases, buildUses is set to false, and any RMW handling (delayFree)
-        // must be handled within the case.
-        switch (intrinsicId)
+        // If we have an RMW intrinsic, we want to preference op1Reg to the target if
+        // op1 is not contained.
+        if (isRMW)
         {
-            case NI_Aes_Decrypt:
-            case NI_Aes_Encrypt:
-                assert((numArgs == 2) && (op1 != nullptr) && (op2 != nullptr));
+            tgtPrefOp1 = !op1->isContained();
+        }
 
-                buildUses = false;
+        if (intrinsicTree->OperIsMemoryLoadOrStore())
+        {
+            srcCount += BuildAddrUses(op1);
+        }
+        else if (tgtPrefOp1)
+        {
+            tgtPrefUse = BuildUse(op1);
+            srcCount++;
+        }
+        else
+        {
+            srcCount += BuildOperandUses(op1);
+        }
 
-                tgtPrefUse = BuildUse(op1);
-                srcCount += 1;
+        if (op2 != nullptr)
+        {
+            if (isRMW)
+            {
                 srcCount += BuildDelayFreeUses(op2);
-                break;
-
-            case NI_Sha1_HashUpdateChoose:
-            case NI_Sha1_HashUpdateMajority:
-            case NI_Sha1_HashUpdateParity:
-                assert((numArgs == 3) && (op2 != nullptr) && (op3 != nullptr));
 
-                if (!op2->isContained())
+                if (op3 != nullptr)
                 {
-                    assert(!op3->isContained());
-
-                    buildUses = false;
-
-                    srcCount += BuildOperandUses(op1);
-                    srcCount += BuildDelayFreeUses(op2);
                     srcCount += BuildDelayFreeUses(op3);
-
-                    setInternalRegsDelayFree = true;
                 }
-
-                buildInternalFloatRegisterDefForNode(intrinsicTree);
-                break;
-
-            case NI_Sha1_FixedRotate:
-                buildInternalFloatRegisterDefForNode(intrinsicTree);
-                break;
-
-            case NI_Sha1_ScheduleUpdate0:
-            case NI_Sha256_HashUpdate1:
-            case NI_Sha256_HashUpdate2:
-            case NI_Sha256_ScheduleUpdate1:
-                assert((numArgs == 3) && (op2 != nullptr) && (op3 != nullptr));
-
-                if (!op2->isContained())
-                {
-                    assert(!op3->isContained());
-
-                    buildUses = false;
-
-                    srcCount += BuildOperandUses(op1);
-                    srcCount += BuildDelayFreeUses(op2);
-                    srcCount += BuildDelayFreeUses(op3);
-                }
-                break;
-
-            case NI_AdvSimd_AbsoluteDifferenceAdd:
-            case NI_AdvSimd_FusedMultiplyAdd:
-            case NI_AdvSimd_FusedMultiplySubtract:
-            case NI_AdvSimd_Arm64_FusedMultiplyAdd:
-            case NI_AdvSimd_Arm64_FusedMultiplySubtract:
-            case NI_AdvSimd_MultiplyAdd:
-            case NI_AdvSimd_MultiplySubtract:
-                assert((numArgs == 3) && (op2 != nullptr) && (op3 != nullptr));
-
-                buildUses = false;
-
-                tgtPrefUse = BuildUse(op1);
-                srcCount += 1;
-                srcCount += BuildDelayFreeUses(op2);
-                srcCount += BuildDelayFreeUses(op3);
-                break;
-
-            case NI_AdvSimd_ExtractAndNarrowHigh:
-
-                assert((numArgs == 2) && (op2 != nullptr));
-
-                buildUses = false;
-
-                tgtPrefUse = BuildUse(op1);
-                srcCount += 1;
-                srcCount += BuildDelayFreeUses(op2);
-                break;
-
-            default:
-                assert((intrinsicId > NI_HW_INTRINSIC_START) && (intrinsicId < NI_HW_INTRINSIC_END));
-                break;
-        }
-
-        if (buildUses)
-        {
-            assert((numArgs > 0) && (numArgs < 4));
-
-            if (intrinsicTree->OperIsMemoryLoadOrStore())
-            {
-                srcCount += BuildAddrUses(op1);
             }
             else
             {
-                srcCount += BuildOperandUses(op1);
-            }
-
-            if (op2 != nullptr)
-            {
-                if (op2->OperIs(GT_HWINTRINSIC) && op2->AsHWIntrinsic()->OperIsMemoryLoad() && op2->isContained())
-                {
-                    srcCount += BuildAddrUses(op2->gtGetOp1());
-                }
-                else if (isRMW)
-                {
-                    srcCount += BuildDelayFreeUses(op2);
-                }
-                else
-                {
-                    srcCount += BuildOperandUses(op2);
-                }
+                srcCount += BuildOperandUses(op2);
 
                 if (op3 != nullptr)
                 {
-                    srcCount += (isRMW) ? BuildDelayFreeUses(op3) : BuildOperandUses(op3);
+                    srcCount += BuildOperandUses(op3);
                 }
             }
         }
index 91ac9fd..a36965e 100644 (file)
@@ -2548,7 +2548,7 @@ void LinearScan::validateIntervals()
 }
 #endif // DEBUG
 
-#ifdef TARGET_XARCH
+#if defined(TARGET_XARCH) || defined(FEATURE_HW_INTRINSICS)
 //------------------------------------------------------------------------
 // setTgtPref: Set a  preference relationship between the given Interval
 //             and a Use RefPosition.
@@ -2579,7 +2579,7 @@ void setTgtPref(Interval* interval, RefPosition* tgtPrefUse)
         }
     }
 }
-#endif // TARGET_XARCH
+#endif // TARGET_XARCH || FEATURE_HW_INTRINSICS
 //------------------------------------------------------------------------
 // BuildDef: Build a RefTypeDef RefPosition for the given node
 //
@@ -2660,7 +2660,7 @@ RefPosition* LinearScan::BuildDef(GenTree* tree, regMaskTP dstCandidates, int mu
         RefInfoListNode* refInfo = listNodePool.GetNode(defRefPosition, tree);
         defList.Append(refInfo);
     }
-#ifdef TARGET_XARCH
+#if defined(TARGET_XARCH) || defined(FEATURE_HW_INTRINSICS)
     setTgtPref(interval, tgtPrefUse);
     setTgtPref(interval, tgtPrefUse2);
 #endif // TARGET_XARCH