Skip to content

Commit ca12d1d

Browse files
[SystemZ] Improve CCMask optimization (#171137)
This commit addresses a shortcoming in the implementation of `combineBR_CCMASK` and `combineSELECT_CCMASK`. In cases where `combineCCMask` was able to reduce the ccmask going into the select or branch to either true (`ccvalid`) or false (`0`), a trivial instruction would be emitted (i.e. either a select that would only ever select one side, or a conditional branch with `true` or `false` as the branch condition). This led under certain circumstances to, e.g., `BRC` instructions being emitted that triggered an assert in the AsmPrinter meant to exclude such branch conditions. For the select case, this commit introduces an early bailout that simply returns the value that would "always" be selected. For the branch case, the commit introduces an additional guard that prevents the DAGCombine from taking effect, thereby preventing the illegal instruction from being emitted.
1 parent 29611f4 commit ca12d1d

File tree

2 files changed

+41
-1
lines changed

2 files changed

+41
-1
lines changed

llvm/lib/Target/SystemZ/SystemZISelLowering.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8887,7 +8887,12 @@ SDValue SystemZTargetLowering::combineBR_CCMASK(SDNode *N,
88878887
int CCMaskVal = CCMask->getZExtValue();
88888888
SDValue Chain = N->getOperand(0);
88898889
SDValue CCReg = N->getOperand(4);
8890-
if (combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG))
8890+
// If combineCMask was able to merge or simplify ccvalid or ccmask, re-emit
8891+
// the modified BR_CCMASK with the new values.
8892+
// In order to avoid conditional branches with full or empty cc masks, do not
8893+
// do this if ccmask is 0 or equal to ccvalid.
8894+
if (combineCCMask(CCReg, CCValidVal, CCMaskVal, DAG) && CCMaskVal != 0 &&
8895+
CCMaskVal != CCValidVal)
88918896
return DAG.getNode(SystemZISD::BR_CCMASK, SDLoc(N), N->getValueType(0),
88928897
Chain,
88938898
DAG.getTargetConstant(CCValidVal, SDLoc(N), MVT::i32),
@@ -8974,6 +8979,13 @@ SDValue SystemZTargetLowering::combineSELECT_CCMASK(
89748979
IsCombinedCCReg = true;
89758980
}
89768981
}
8982+
// If the condition is trivially false or trivially true after
8983+
// combineCCMask, just collapse this SELECT_CCMASK to the indicated value
8984+
// (possibly modified by constructCCSDValsFromSELECT).
8985+
if (CCMaskVal == 0)
8986+
return FalseVal;
8987+
if (CCMaskVal == CCValidVal)
8988+
return TrueVal;
89778989

89788990
if (IsCombinedCCReg)
89798991
return DAG.getNode(
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
; Test that a conditional branch with a discoverably trivial condition
2+
; does not result in an invalid conditional branch instruction.
3+
;
4+
; RUN: llc < %s -verify-machineinstrs -mtriple=s390x-linux-gnu -mcpu=z13 \
5+
; RUN: --stop-after=systemz-isel | FileCheck %s
6+
7+
@g_1 = dso_local local_unnamed_addr global i64 0, align 8
8+
@g_2 = dso_local local_unnamed_addr global i32 0, align 4
9+
10+
define dso_local void @f1() local_unnamed_addr #1 {
11+
entry:
12+
;CHECK-LABEL: f1
13+
;CHECK-NOT: BRC 14, 0, %bb.2
14+
%0 = load i64, ptr @g_1, align 8
15+
%tobool.not = icmp eq i64 %0, 0
16+
%sub.i = select i1 %tobool.not, i8 4, i8 3
17+
%conv1 = zext nneg i8 %sub.i to i32
18+
store i32 %conv1, ptr @g_2, align 4
19+
%.pr = load i32, ptr @g_2, align 4
20+
%tobool5.not = icmp eq i32 %.pr, 0
21+
br i1 %tobool5.not, label %for.cond, label %lbl_1
22+
23+
lbl_1:
24+
br label %lbl_1
25+
26+
for.cond:
27+
br label %for.cond
28+
}

0 commit comments

Comments
 (0)