@@ -14189,7 +14189,16 @@ SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
14189
14189
return SDValue();
14190
14190
14191
14191
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)
14193
14202
return SDValue();
14194
14203
14195
14204
if (!isNullConstant(LaneMask.getOperand(1)) ||
@@ -14210,8 +14219,13 @@ SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
14210
14219
// it's positive, otherwise the difference plus the element size if it's
14211
14220
// negative: pos_diff = diff < 0 ? (diff + 7) : diff
14212
14221
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
+
14213
14227
// 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 )
14215
14229
return SDValue();
14216
14230
// Make sure it's checking if the difference is less than 0
14217
14231
if (!isNullConstant(Select.getOperand(1)) ||
@@ -14243,22 +14257,26 @@ SDValue tryWhileWRFromOR(SDValue Op, SelectionDAG &DAG,
14243
14257
} else if (LaneMask.getOperand(2) != Diff)
14244
14258
return SDValue();
14245
14259
14246
- SDValue StorePtr = Diff .getOperand(0);
14247
- SDValue ReadPtr = Diff .getOperand(1);
14260
+ SDValue StorePtr = NonAbsDiff .getOperand(0);
14261
+ SDValue ReadPtr = NonAbsDiff .getOperand(1);
14248
14262
14249
14263
unsigned IntrinsicID = 0;
14250
14264
switch (EltSize) {
14251
14265
case 1:
14252
- IntrinsicID = Intrinsic::aarch64_sve_whilewr_b;
14266
+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_b
14267
+ : Intrinsic::aarch64_sve_whilerw_b;
14253
14268
break;
14254
14269
case 2:
14255
- IntrinsicID = Intrinsic::aarch64_sve_whilewr_h;
14270
+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_h
14271
+ : Intrinsic::aarch64_sve_whilerw_h;
14256
14272
break;
14257
14273
case 4:
14258
- IntrinsicID = Intrinsic::aarch64_sve_whilewr_s;
14274
+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_s
14275
+ : Intrinsic::aarch64_sve_whilerw_s;
14259
14276
break;
14260
14277
case 8:
14261
- IntrinsicID = Intrinsic::aarch64_sve_whilewr_d;
14278
+ IntrinsicID = WriteAfterRead ? Intrinsic::aarch64_sve_whilewr_d
14279
+ : Intrinsic::aarch64_sve_whilerw_d;
14262
14280
break;
14263
14281
default:
14264
14282
return SDValue();
0 commit comments