-
Notifications
You must be signed in to change notification settings - Fork 14.3k
[X86] Fix miscompile in combineShiftRightArithmetic #86597
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -47406,10 +47406,13 @@ static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG, | |
return DAG.getNode(X86ISD::VSRAV, DL, N->getVTList(), N0, ShrAmtVal); | ||
} | ||
|
||
// fold (ashr (shl, a, [56,48,32,24,16]), SarConst) | ||
// into (shl, (sext (a), [56,48,32,24,16] - SarConst)) or | ||
// into (lshr, (sext (a), SarConst - [56,48,32,24,16])) | ||
// depending on sign of (SarConst - [56,48,32,24,16]) | ||
// fold (SRA (SHL X, ShlConst), SraConst) | ||
// into (SHL (sext_in_reg X), ShlConst - SraConst) | ||
// or (sext_in_reg X) | ||
// or (SRA (sext_in_reg X), SraConst - ShlConst) | ||
// depending on relation between SraConst and ShlConst. | ||
// We only do this if (Size - ShlConst) is equal to 8, 16 or 32. That allows | ||
// us to do the sext_in_reg from corresponding bit. | ||
|
||
// sexts in X86 are MOVs. The MOVs have the same code size | ||
// as above SHIFTs (only SHIFT on 1 has lower code size). | ||
|
@@ -47425,29 +47428,29 @@ static SDValue combineShiftRightArithmetic(SDNode *N, SelectionDAG &DAG, | |
SDValue N00 = N0.getOperand(0); | ||
SDValue N01 = N0.getOperand(1); | ||
APInt ShlConst = N01->getAsAPIntVal(); | ||
APInt SarConst = N1->getAsAPIntVal(); | ||
APInt SraConst = N1->getAsAPIntVal(); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you fix this comment on line 47412 There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you also fix 47411 to say There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've cleaned up a bit now:
|
||
EVT CVT = N1.getValueType(); | ||
|
||
if (SarConst.isNegative()) | ||
if (CVT != N01.getValueType()) | ||
return SDValue(); | ||
if (SraConst.isNegative()) | ||
return SDValue(); | ||
|
||
for (MVT SVT : { MVT::i8, MVT::i16, MVT::i32 }) { | ||
unsigned ShiftSize = SVT.getSizeInBits(); | ||
// skipping types without corresponding sext/zext and | ||
// ShlConst that is not one of [56,48,32,24,16] | ||
// Only deal with (Size - ShlConst) being equal to 8, 16 or 32. | ||
if (ShiftSize >= Size || ShlConst != Size - ShiftSize) | ||
continue; | ||
SDLoc DL(N); | ||
SDValue NN = | ||
DAG.getNode(ISD::SIGN_EXTEND_INREG, DL, VT, N00, DAG.getValueType(SVT)); | ||
SarConst = SarConst - (Size - ShiftSize); | ||
if (SarConst == 0) | ||
if (SraConst.eq(ShlConst)) | ||
return NN; | ||
if (SarConst.isNegative()) | ||
if (SraConst.ult(ShlConst)) | ||
return DAG.getNode(ISD::SHL, DL, VT, NN, | ||
DAG.getConstant(-SarConst, DL, CVT)); | ||
DAG.getConstant(ShlConst - SraConst, DL, CVT)); | ||
return DAG.getNode(ISD::SRA, DL, VT, NN, | ||
DAG.getConstant(SarConst, DL, CVT)); | ||
DAG.getConstant(SraConst - ShlConst, DL, CVT)); | ||
} | ||
return SDValue(); | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
between*