diff --git a/llvm/lib/Target/M68k/M68kISelLowering.cpp b/llvm/lib/Target/M68k/M68kISelLowering.cpp index 594ea9f48c201..cf666862b775d 100644 --- a/llvm/lib/Target/M68k/M68kISelLowering.cpp +++ b/llvm/lib/Target/M68k/M68kISelLowering.cpp @@ -1667,8 +1667,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); } diff --git a/llvm/test/CodeGen/M68k/Bits/btst.ll b/llvm/test/CodeGen/M68k/Bits/btst.ll new file mode 100644 index 0000000000000..6c96f906d1812 --- /dev/null +++ b/llvm/test/CodeGen/M68k/Bits/btst.ll @@ -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 +}