Skip to content
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

likely arm64 miscompile #55201

Closed
regehr opened this issue Apr 30, 2022 · 7 comments
Closed

likely arm64 miscompile #55201

regehr opened this issue Apr 30, 2022 · 7 comments

Comments

@regehr
Copy link
Contributor

regehr commented Apr 30, 2022

ok this has been llvm-reduced but it's still a bit complex, sorry!

define i32 @f(i32 %x) {
  %or1 = or i32 %x, 1
  %sh1 = shl i32 %or1, 5
  %sh2 = lshr i32 %x, 27
  %1 = and i32 %sh2, 1
  %r = or i32 %sh1, %1
  ret i32 %r
}

we believe that f(0xf0000000) -> 32 and that is what we get when using global isel, and also when compiling this code for x64.

on the other hand, the default arm64 backend from top of tree gives f(0xf0000000) -> 62

we don't think there's any UB going on here, seems like a straight-up miscompile

cc @ornata @nunoplopes @ryan-berger @nbushehri @aqjune @Hatsunespica

@llvmbot
Copy link
Collaborator

llvmbot commented Apr 30, 2022

@llvm/issue-subscribers-backend-aarch64

@regehr
Copy link
Contributor Author

regehr commented Apr 30, 2022

bad asm from the default backend

_f:
	ror	w8, w0, #27
	orr	w0, w8, #0x20
	ret

good asm from global isel:

_f: 
	orr	w8, w0, #0x1
	ubfx	w9, w0, #27, #1
	orr	w0, w9, w8, lsl #5
	ret

@topperc
Copy link
Collaborator

topperc commented Apr 30, 2022

-mtriple=riscv32 -mattr=+zbb produces something equivalent to the bad AArch64 code.

@topperc
Copy link
Collaborator

topperc commented Apr 30, 2022

Seems to be something in the rotate matching. x86 picks a funnel shift instead.

@topperc
Copy link
Collaborator

topperc commented Apr 30, 2022

This patch fixes it

diff --git a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
index 71618eb2bd7c..ac9670746c53 100644
--- a/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/DAGCombiner.cpp
@@ -7482,7 +7482,7 @@ SDValue DAGCombiner::MatchRotate(SDValue LHS, SDValue RHS, const SDLoc &DL) {
 
   // TODO: Support pre-legalization funnel-shift by constant.
   bool IsRotate = LHSShift.getOperand(0) == RHSShift.getOperand(0);
-  if (!IsRotate && !(HasFSHL || HasFSHR)) {
+  if (!IsRotate && !(HasFSHL || HasFSHR)) {
     if (TLI.isTypeLegal(VT) && LHS.hasOneUse() && RHS.hasOneUse() &&
         ISD::matchBinaryPredicate(LHSShiftAmt, RHSShiftAmt, MatchRotateSum) &&
         !LHSMask && !RHSMask) {
       // Look for a disguised rotate by constant.

We might be able to do better. The block of code behind that if forgot to do anything with LHSMask and RHSMask so this patch makes it so we don't enter the code when we need to do something with them.

@topperc
Copy link
Collaborator

topperc commented Apr 30, 2022

Candidate patch https://reviews.llvm.org/D124711

@topperc
Copy link
Collaborator

topperc commented Apr 30, 2022

Fixed by 6affe87

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants