@@ -14189,7 +14189,16 @@ SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
1418914189 return SDValue();
1419014190
1419114191 SDValue Diff = Cmp.getOperand(0);
14192- if (Diff.getOpcode() != ISD::SUB || Diff.getValueType() != MVT::i64)
14192+ SDValue NonAbsDiff = Diff;
14193+ bool WriteAfterRead = true;
14194+ // A read-after-write will have an abs call on the diff
14195+ if (Diff.getOpcode() == ISD::ABS) {
14196+ NonAbsDiff = Diff.getOperand(0);
14197+ WriteAfterRead = false;
14198+ }
14199+
14200+ if (NonAbsDiff.getOpcode() != ISD::SUB ||
14201+ NonAbsDiff.getValueType() != MVT::i64)
1419314202 return SDValue();
1419414203
1419514204 if (!isNullConstant(LaneMask.getOperand(1)) ||
@@ -14210,8 +14219,13 @@ SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
1421014219 // it's positive, otherwise the difference plus the element size if it's
1421114220 // negative: pos_diff = diff < 0 ? (diff + 7) : diff
1421214221 SDValue Select = DiffDiv.getOperand(0);
14222+ SDValue SelectOp3 = Select.getOperand(3);
14223+ // Check for an abs in the case of a read-after-write
14224+ if (!WriteAfterRead && SelectOp3.getOpcode() == ISD::ABS)
14225+ SelectOp3 = SelectOp3.getOperand(0);
14226+
1421314227 // Make sure the difference is being compared by the select
14214- if (Select.getOpcode() != ISD::SELECT_CC || Select.getOperand(3) != Diff )
14228+ if (Select.getOpcode() != ISD::SELECT_CC || SelectOp3 != NonAbsDiff )
1421514229 return SDValue();
1421614230 // Make sure it's checking if the difference is less than 0
1421714231 if (!isNullConstant(Select.getOperand(1)) ||
@@ -14243,22 +14257,26 @@ SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
1424314257 } else if (LaneMask.getOperand(2) != Diff)
1424414258 return SDValue();
1424514259
14246- SDValue StorePtr = Diff .getOperand(0);
14247- SDValue ReadPtr = Diff .getOperand(1);
14260+ SDValue StorePtr = NonAbsDiff .getOperand(0);
14261+ SDValue ReadPtr = NonAbsDiff .getOperand(1);
1424814262
1424914263 unsigned IntrinsicID = 0;
1425014264 switch (EltSize) {
1425114265 case 1:
14252- IntrinsicID = Intrinsic::aarch64_sve_whilewr_b;
14266+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_b
14267+ : Intrinsic::aarch64_sve_whilerw_b;
1425314268 break;
1425414269 case 2:
14255- IntrinsicID = Intrinsic::aarch64_sve_whilewr_h;
14270+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_h
14271+ : Intrinsic::aarch64_sve_whilerw_h;
1425614272 break;
1425714273 case 4:
14258- IntrinsicID = Intrinsic::aarch64_sve_whilewr_s;
14274+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_s
14275+ : Intrinsic::aarch64_sve_whilerw_s;
1425914276 break;
1426014277 case 8:
14261- IntrinsicID = Intrinsic::aarch64_sve_whilewr_d;
14278+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_d
14279+ : Intrinsic::aarch64_sve_whilerw_d;
1426214280 break;
1426314281 default:
1426414282 return SDValue();
0 commit comments