Index: llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp =================================================================== --- llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp +++ llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp @@ -1306,6 +1306,7 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert, MachineRegisterInfo &MRI) { assert(Reg.isValid() && "Expected valid register!"); + bool HasZext = false; while (MachineInstr *MI = getDefIgnoringCopies(Reg, MRI)) { unsigned Opc = MI->getOpcode(); @@ -1319,6 +1320,9 @@ // on the truncated x is the same as the bit number on x. if (Opc == TargetOpcode::G_ANYEXT || Opc == TargetOpcode::G_ZEXT || Opc == TargetOpcode::G_TRUNC) { + if (Opc == TargetOpcode::G_ZEXT) + HasZext = true; + Register NextReg = MI->getOperand(1).getReg(); // Did we find something worth folding? if (!NextReg.isValid() || !MRI.hasOneNonDBGUse(NextReg)) @@ -1347,8 +1351,12 @@ std::swap(ConstantReg, TestReg); VRegAndVal = getConstantVRegValWithLookThrough(ConstantReg, MRI); } - if (VRegAndVal) - C = VRegAndVal->Value.getSExtValue(); + if (VRegAndVal) { + if (HasZext) + C = VRegAndVal->Value.getZExtValue(); + else + C = VRegAndVal->Value.getSExtValue(); + } break; } case TargetOpcode::G_ASHR: Index: llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-xor-tbz-tbnz.mir =================================================================== --- llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-xor-tbz-tbnz.mir +++ llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-xor-tbz-tbnz.mir @@ -117,6 +117,38 @@ RET_ReallyLR ... --- +name: dont_flip_eq_zext +alignment: 4 +legalized: true +regBankSelected: true +tracksRegLiveness: true +body: | + ; CHECK-LABEL: name: dont_flip_eq_zext + ; CHECK: bb.0: + ; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000) + ; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $wzr + ; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, [[COPY]], %subreg.sub_32 + ; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]] + ; CHECK: TBNZX [[COPY1]], 63, %bb.1 + ; CHECK: B %bb.0 + ; CHECK: bb.1: + ; CHECK: RET_ReallyLR + bb.0: + successors: %bb.0(0x40000000), %bb.1(0x40000000) + + %1:gpr(s32) = G_CONSTANT i32 0 + %3:gpr(s32) = G_CONSTANT i32 -1 + %4:gpr(s32) = G_XOR %1, %3 + %5:gpr(s64) = G_ZEXT %4(s32) + %15:gpr(s64) = G_CONSTANT i64 0 + %13:gpr(s32) = G_ICMP intpred(slt), %5(s64), %15 + %7:gpr(s1) = G_TRUNC %13(s32) + G_BRCOND %7(s1), %bb.1 + G_BR %bb.0 + bb.1: + RET_ReallyLR +... +--- name: dont_flip_ne alignment: 4 legalized: true