Skip to content

Commit 80f974e

Browse files
guopeilintstellar
guopeilin
authored andcommitted
[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 (cherry picked from commit 5f48c14)
1 parent 5b95eb0 commit 80f974e

File tree

2 files changed

+42
-2
lines changed

2 files changed

+42
-2
lines changed

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

+10-2
Original file line numberDiff line numberDiff line change
@@ -1301,6 +1301,7 @@ static AArch64CC::CondCode changeICMPPredToAArch64CC(CmpInst::Predicate P) {
13011301
static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
13021302
MachineRegisterInfo &MRI) {
13031303
assert(Reg.isValid() && "Expected valid register!");
1304+
bool HasZext = false;
13041305
while (MachineInstr *MI = getDefIgnoringCopies(Reg, MRI)) {
13051306
unsigned Opc = MI->getOpcode();
13061307

@@ -1314,6 +1315,9 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
13141315
// on the truncated x is the same as the bit number on x.
13151316
if (Opc == TargetOpcode::G_ANYEXT || Opc == TargetOpcode::G_ZEXT ||
13161317
Opc == TargetOpcode::G_TRUNC) {
1318+
if (Opc == TargetOpcode::G_ZEXT)
1319+
HasZext = true;
1320+
13171321
Register NextReg = MI->getOperand(1).getReg();
13181322
// Did we find something worth folding?
13191323
if (!NextReg.isValid() || !MRI.hasOneNonDBGUse(NextReg))
@@ -1342,8 +1346,12 @@ static Register getTestBitReg(Register Reg, uint64_t &Bit, bool &Invert,
13421346
std::swap(ConstantReg, TestReg);
13431347
VRegAndVal = getConstantVRegValWithLookThrough(ConstantReg, MRI);
13441348
}
1345-
if (VRegAndVal)
1346-
C = VRegAndVal->Value.getSExtValue();
1349+
if (VRegAndVal) {
1350+
if (HasZext)
1351+
C = VRegAndVal->Value.getZExtValue();
1352+
else
1353+
C = VRegAndVal->Value.getSExtValue();
1354+
}
13471355
break;
13481356
}
13491357
case TargetOpcode::G_ASHR:

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

+32
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)