[M68k] Fix reverse BTST condition causing opposite failure/success logic (#153086)
Given the test case: ```llvm define fastcc i16 @testbtst(i16 %a) nounwind { entry: switch i16 %a, label %no [ i16 11, label %yes i16 10, label %yes i16 9, label %yes i16 4, label %yes i16 3, label %yes i16 2, label %yes ] yes: ret i16 1 no: ret i16 0 } ``` We currently get this result: ```asm testbtst: ; @testbtst ; %bb.0: ; %entry move.l %d0, %d1 and.l #65535, %d1 sub.l #11, %d1 bhi .LBB0_3 ; %bb.1: ; %entry and.l #65535, %d0 move.l #3612, %d1 btst %d0, %d1 bne .LBB0_3 ; <------- Erroneous condition ; %bb.2: ; %yes moveq #1, %d0 rts .LBB0_3: ; %no moveq #0, %d0 rts ``` The cause of this is a line that explicitly reverses the `btst` condition code. But on M68k, `btst` sets condition codes the same as `and` with a bitmask, meaning `EQ` indicates failure (bit is zero) and not success, so the condition does not need to be reversed. In my testing, I've only been able to get switch statements to lower to `btst`, so I wasn't able to explicitly test other options for lowering. But (if possible to trigger) I believe they have the same logical error. For example, in `LowerAndToBTST()`, a comment specifies that it's lowering a case where the `and` result is compared against zero, which means the corresponding `btst` condition should also not be reversed. This patch simply flips the ternary expression in `getBitTestCondition()` to match the ISD condition code with the same M68k code, instead of the opposite.
This commit is contained in:
parent
4e6c88be7c
commit
45e2c50256
@ -1666,8 +1666,8 @@ static SDValue getBitTestCondition(SDValue Src, SDValue BitNo, ISD::CondCode CC,
|
||||
|
||||
SDValue BTST = DAG.getNode(M68kISD::BTST, DL, MVT::i32, Src, BitNo);
|
||||
|
||||
// NOTE BTST sets CCR.Z flag
|
||||
M68k::CondCode Cond = CC == ISD::SETEQ ? M68k::COND_NE : M68k::COND_EQ;
|
||||
// NOTE BTST sets CCR.Z flag if bit is 0, same as AND with bitmask
|
||||
M68k::CondCode Cond = CC == ISD::SETEQ ? M68k::COND_EQ : M68k::COND_NE;
|
||||
return DAG.getNode(M68kISD::SETCC, DL, MVT::i8,
|
||||
DAG.getConstant(Cond, DL, MVT::i8), BTST);
|
||||
}
|
||||
|
62
llvm/test/CodeGen/M68k/Bits/btst.ll
Normal file
62
llvm/test/CodeGen/M68k/Bits/btst.ll
Normal file
@ -0,0 +1,62 @@
|
||||
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
|
||||
; RUN: llc < %s -mtriple=m68k-freestanding -verify-machineinstrs | FileCheck %s
|
||||
|
||||
define fastcc i16 @switch_to_btst(i16 %a) nounwind {
|
||||
; CHECK-LABEL: switch_to_btst:
|
||||
; CHECK: ; %bb.0: ; %entry
|
||||
; CHECK-NEXT: move.l %d0, %d1
|
||||
; CHECK-NEXT: and.l #65535, %d1
|
||||
; CHECK-NEXT: sub.l #11, %d1
|
||||
; CHECK-NEXT: bhi .LBB0_3
|
||||
; CHECK-NEXT: ; %bb.1: ; %entry
|
||||
; CHECK-NEXT: and.l #65535, %d0
|
||||
; CHECK-NEXT: move.l #3612, %d1
|
||||
; CHECK-NEXT: btst %d0, %d1
|
||||
; CHECK-NEXT: beq .LBB0_3
|
||||
; CHECK-NEXT: ; %bb.2: ; %match
|
||||
; CHECK-NEXT: moveq #1, %d0
|
||||
; CHECK-NEXT: rts
|
||||
; CHECK-NEXT: .LBB0_3: ; %no_match
|
||||
; CHECK-NEXT: moveq #0, %d0
|
||||
; CHECK-NEXT: rts
|
||||
entry:
|
||||
switch i16 %a, label %no_match [
|
||||
i16 11, label %match
|
||||
i16 10, label %match
|
||||
i16 9, label %match
|
||||
i16 4, label %match
|
||||
i16 3, label %match
|
||||
i16 2, label %match
|
||||
]
|
||||
|
||||
match:
|
||||
ret i16 1
|
||||
|
||||
no_match:
|
||||
ret i16 0
|
||||
}
|
||||
|
||||
define fastcc i16 @and_mask_to_btst(i8 %a, i8 %b) nounwind {
|
||||
; CHECK-LABEL: and_mask_to_btst:
|
||||
; CHECK: ; %bb.0:
|
||||
; CHECK-NEXT: and.l #7, %d1
|
||||
; CHECK-NEXT: btst %d1, %d0
|
||||
; CHECK-NEXT: beq .LBB1_1
|
||||
; CHECK-NEXT: ; %bb.2: ; %cond_false
|
||||
; CHECK-NEXT: moveq #0, %d0
|
||||
; CHECK-NEXT: rts
|
||||
; CHECK-NEXT: .LBB1_1: ; %cond_true
|
||||
; CHECK-NEXT: moveq #1, %d0
|
||||
; CHECK-NEXT: rts
|
||||
%33 = and i8 %b, 7
|
||||
%34 = shl nuw i8 1, %33
|
||||
%35 = and i8 %34, %a
|
||||
%.not = icmp eq i8 %35, 0
|
||||
br i1 %.not, label %cond_true, label %cond_false
|
||||
|
||||
cond_true:
|
||||
ret i16 1
|
||||
|
||||
cond_false:
|
||||
ret i16 0
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user