Skip to content

Commit 5f48c14

Browse files
author
guopeilin
committed
[AArch64][GlobalISel] Use ZExtValue for zext(xor) when invert tb(n)z
Currently, we use SExtValue to decide whether to invert tbz or tbnz. However, for the case zext (xor x, c), we should use ZExt rather than SExt otherwise we will generate totally opposite branches. Reviewed By: paquette Differential Revision: https://reviews.llvm.org/D108755
1 parent fa69ccd commit 5f48c14

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

llvm/lib/Target/AArch64/GISel/AArch64InstructionSelector.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,6 +1314,7 @@ static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
13141314
static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
13151315
MachineRegisterInfo &MRI) {
13161316
assert(Reg.isValid() && "Expected valid register!");
1317+
bool HasZext = false;
13171318
while (MachineInstr *MI = getDefIgnoringCopies(Reg, MRI)) {
13181319
unsigned Opc = MI->getOpcode();
13191320

@@ -1327,6 +1328,9 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
13271328
// on the truncated x is the same as the bit number on x.
13281329
if (Opc == TargetOpcode::G_ANYEXT || Opc == TargetOpcode::G_ZEXT ||
13291330
Opc == TargetOpcode::G_TRUNC) {
1331+
if (Opc == TargetOpcode::G_ZEXT)
1332+
HasZext = true;
1333+
13301334
Register NextReg = MI->getOperand(1).getReg();
13311335
// Did we find something worth folding?
13321336
if (!NextReg.isValid() || !MRI.hasOneNonDBGUse(NextReg))
@@ -1355,8 +1359,12 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
13551359
std::swap(ConstantReg, TestReg);
13561360
VRegAndVal = getConstantVRegValWithLookThrough(ConstantReg, MRI);
13571361
}
1358-
if (VRegAndVal)
1359-
C = VRegAndVal->Value.getSExtValue();
1362+
if (VRegAndVal) {
1363+
if (HasZext)
1364+
C = VRegAndVal->Value.getZExtValue();
1365+
else
1366+
C = VRegAndVal->Value.getSExtValue();
1367+
}
13601368
break;
13611369
}
13621370
case TargetOpcode::G_ASHR:

llvm/test/CodeGen/AArch64/GlobalISel/opt-fold-xor-tbz-tbnz.mir

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,38 @@ body: |
117117
RET_ReallyLR
118118
...
119119
---
120+
name: dont_flip_eq_zext
121+
alignment: 4
122+
legalized: true
123+
regBankSelected: true
124+
tracksRegLiveness: true
125+
body: |
126+
; CHECK-LABEL: name: dont_flip_eq_zext
127+
; CHECK: bb.0:
128+
; CHECK: successors: %bb.0(0x40000000), %bb.1(0x40000000)
129+
; CHECK: [[COPY:%[0-9]+]]:gpr32 = COPY $wzr
130+
; CHECK: [[SUBREG_TO_REG:%[0-9]+]]:gpr64all = SUBREG_TO_REG 0, [[COPY]], %subreg.sub_32
131+
; CHECK: [[COPY1:%[0-9]+]]:gpr64 = COPY [[SUBREG_TO_REG]]
132+
; CHECK: TBNZX [[COPY1]], 63, %bb.1
133+
; CHECK: B %bb.0
134+
; CHECK: bb.1:
135+
; CHECK: RET_ReallyLR
136+
bb.0:
137+
successors: %bb.0(0x40000000), %bb.1(0x40000000)
138+
139+
%1:gpr(s32) = G_CONSTANT i32 0
140+
%3:gpr(s32) = G_CONSTANT i32 -1
141+
%4:gpr(s32) = G_XOR %1, %3
142+
%5:gpr(s64) = G_ZEXT %4(s32)
143+
%15:gpr(s64) = G_CONSTANT i64 0
144+
%13:gpr(s32) = G_ICMP intpred(slt), %5(s64), %15
145+
%7:gpr(s1) = G_TRUNC %13(s32)
146+
G_BRCOND %7(s1), %bb.1
147+
G_BR %bb.0
148+
bb.1:
149+
RET_ReallyLR
150+
...
151+
---
120152
name: dont_flip_ne
121153
alignment: 4
122154
legalized: true

0 commit comments

Comments
 (0)