Skip to content

Commit 38c2366

Browse files
committed
[AArch64][GlobalISel] Recognise some CCMPri
This is a simple addition to emitConditionalComparison, to match CCMP with immediates using getIConstantVRegValWithLookThrough, letting it select the CCMPri variants of the instructions. Differential Revision: https://reviews.llvm.org/D131073
1 parent b2c9ff7 commit 38c2366

File tree

2 files changed

+53
-93
lines changed

2 files changed

+53
-93
lines changed

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

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4821,8 +4821,13 @@ MachineInstr *AArch64InstructionSelector::emitConditionalComparison(
48214821
LLT OpTy = MRI.getType(LHS);
48224822
assert(OpTy.getSizeInBits() == 32 || OpTy.getSizeInBits() == 64);
48234823
unsigned CCmpOpc;
4824+
Optional<ValueAndVReg> C;
48244825
if (CmpInst::isIntPredicate(CC)) {
4825-
CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMPWr : AArch64::CCMPXr;
4826+
C = getIConstantVRegValWithLookThrough(RHS, MRI);
4827+
if (C && C->Value.ult(32))
4828+
CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMPWi : AArch64::CCMPXi;
4829+
else
4830+
CCmpOpc = OpTy.getSizeInBits() == 32 ? AArch64::CCMPWr : AArch64::CCMPXr;
48264831
} else {
48274832
switch (OpTy.getSizeInBits()) {
48284833
case 16:
@@ -4841,7 +4846,12 @@ MachineInstr *AArch64InstructionSelector::emitConditionalComparison(
48414846
AArch64CC::CondCode InvOutCC = AArch64CC::getInvertedCondCode(OutCC);
48424847
unsigned NZCV = AArch64CC::getNZCVToSatisfyCondCode(InvOutCC);
48434848
auto CCmp =
4844-
MIB.buildInstr(CCmpOpc, {}, {LHS, RHS}).addImm(NZCV).addImm(Predicate);
4849+
MIB.buildInstr(CCmpOpc, {}, {LHS});
4850+
if (C)
4851+
CCmp.addImm(C->Value.getZExtValue());
4852+
else
4853+
CCmp.addReg(RHS);
4854+
CCmp.addImm(NZCV).addImm(Predicate);
48454855
constrainSelectedInstRegOperands(*CCmp, TII, TRI, RBI);
48464856
return &*CCmp;
48474857
}

llvm/test/CodeGen/AArch64/arm64-ccmp.ll

Lines changed: 41 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,9 @@ define i64 @gccbug(i64 %x0, i64 %x1) {
536536
; GISEL-LABEL: gccbug:
537537
; GISEL: ; %bb.0:
538538
; GISEL-NEXT: mov w8, #2
539-
; GISEL-NEXT: mov w9, #4
540539
; GISEL-NEXT: cmp x0, #2
541-
; GISEL-NEXT: ccmp x0, x9, #4, ne
542-
; GISEL-NEXT: ccmp x1, xzr, #0, eq
540+
; GISEL-NEXT: ccmp x0, #4, #4, ne
541+
; GISEL-NEXT: ccmp x1, #0, #0, eq
543542
; GISEL-NEXT: csinc x0, x8, xzr, eq
544543
; GISEL-NEXT: ret
545544
%cmp0 = icmp eq i64 %x1, 0
@@ -554,25 +553,14 @@ define i64 @gccbug(i64 %x0, i64 %x1) {
554553
}
555554

556555
define i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) {
557-
; SDISEL-LABEL: select_ororand:
558-
; SDISEL: ; %bb.0:
559-
; SDISEL-NEXT: cmp w3, #4
560-
; SDISEL-NEXT: ccmp w2, #2, #0, gt
561-
; SDISEL-NEXT: ccmp w1, #13, #2, ge
562-
; SDISEL-NEXT: ccmp w0, #0, #4, ls
563-
; SDISEL-NEXT: csel w0, w3, wzr, eq
564-
; SDISEL-NEXT: ret
565-
;
566-
; GISEL-LABEL: select_ororand:
567-
; GISEL: ; %bb.0:
568-
; GISEL-NEXT: mov w8, #13
569-
; GISEL-NEXT: mov w9, #2
570-
; GISEL-NEXT: cmp w3, #4
571-
; GISEL-NEXT: ccmp w2, w9, #0, gt
572-
; GISEL-NEXT: ccmp w1, w8, #2, ge
573-
; GISEL-NEXT: ccmp w0, wzr, #4, ls
574-
; GISEL-NEXT: csel w0, w3, wzr, eq
575-
; GISEL-NEXT: ret
556+
; CHECK-LABEL: select_ororand:
557+
; CHECK: ; %bb.0:
558+
; CHECK-NEXT: cmp w3, #4
559+
; CHECK-NEXT: ccmp w2, #2, #0, gt
560+
; CHECK-NEXT: ccmp w1, #13, #2, ge
561+
; CHECK-NEXT: ccmp w0, #0, #4, ls
562+
; CHECK-NEXT: csel w0, w3, wzr, eq
563+
; CHECK-NEXT: ret
576564
%c0 = icmp eq i32 %w0, 0
577565
%c1 = icmp ugt i32 %w1, 13
578566
%c2 = icmp slt i32 %w2, 2
@@ -585,21 +573,13 @@ define i32 @select_ororand(i32 %w0, i32 %w1, i32 %w2, i32 %w3) {
585573
}
586574

587575
define i32 @select_andor(i32 %v1, i32 %v2, i32 %v3) {
588-
; SDISEL-LABEL: select_andor:
589-
; SDISEL: ; %bb.0:
590-
; SDISEL-NEXT: cmp w1, w2
591-
; SDISEL-NEXT: ccmp w0, #0, #4, lt
592-
; SDISEL-NEXT: ccmp w0, w1, #0, eq
593-
; SDISEL-NEXT: csel w0, w0, w1, eq
594-
; SDISEL-NEXT: ret
595-
;
596-
; GISEL-LABEL: select_andor:
597-
; GISEL: ; %bb.0:
598-
; GISEL-NEXT: cmp w1, w2
599-
; GISEL-NEXT: ccmp w0, wzr, #4, lt
600-
; GISEL-NEXT: ccmp w0, w1, #0, eq
601-
; GISEL-NEXT: csel w0, w0, w1, eq
602-
; GISEL-NEXT: ret
576+
; CHECK-LABEL: select_andor:
577+
; CHECK: ; %bb.0:
578+
; CHECK-NEXT: cmp w1, w2
579+
; CHECK-NEXT: ccmp w0, #0, #4, lt
580+
; CHECK-NEXT: ccmp w0, w1, #0, eq
581+
; CHECK-NEXT: csel w0, w0, w1, eq
582+
; CHECK-NEXT: ret
603583
%c0 = icmp eq i32 %v1, %v2
604584
%c1 = icmp sge i32 %v2, %v3
605585
%c2 = icmp eq i32 %v1, 0
@@ -1001,24 +981,14 @@ define i32 @f128_select_and_olt_oge(fp128 %v0, fp128 %v1, fp128 %v2, fp128 %v3,
1001981
; This testcase resembles the core problem of http://llvm.org/PR39550
1002982
; (an OR operation is 2 levels deep but needs to be implemented first)
1003983
define i32 @deep_or(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
1004-
; SDISEL-LABEL: deep_or:
1005-
; SDISEL: ; %bb.0:
1006-
; SDISEL-NEXT: cmp w2, #20
1007-
; SDISEL-NEXT: ccmp w2, #15, #4, ne
1008-
; SDISEL-NEXT: ccmp w1, #0, #4, eq
1009-
; SDISEL-NEXT: ccmp w0, #0, #4, ne
1010-
; SDISEL-NEXT: csel w0, w4, w5, ne
1011-
; SDISEL-NEXT: ret
1012-
;
1013-
; GISEL-LABEL: deep_or:
1014-
; GISEL: ; %bb.0:
1015-
; GISEL-NEXT: mov w8, #15
1016-
; GISEL-NEXT: cmp w2, #20
1017-
; GISEL-NEXT: ccmp w2, w8, #4, ne
1018-
; GISEL-NEXT: ccmp w1, wzr, #4, eq
1019-
; GISEL-NEXT: ccmp w0, wzr, #4, ne
1020-
; GISEL-NEXT: csel w0, w4, w5, ne
1021-
; GISEL-NEXT: ret
984+
; CHECK-LABEL: deep_or:
985+
; CHECK: ; %bb.0:
986+
; CHECK-NEXT: cmp w2, #20
987+
; CHECK-NEXT: ccmp w2, #15, #4, ne
988+
; CHECK-NEXT: ccmp w1, #0, #4, eq
989+
; CHECK-NEXT: ccmp w0, #0, #4, ne
990+
; CHECK-NEXT: csel w0, w4, w5, ne
991+
; CHECK-NEXT: ret
1022992
%c0 = icmp ne i32 %a0, 0
1023993
%c1 = icmp ne i32 %a1, 0
1024994
%c2 = icmp eq i32 %a2, 15
@@ -1033,24 +1003,14 @@ define i32 @deep_or(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
10331003

10341004
; Variation of deep_or, we still need to implement the OR first though.
10351005
define i32 @deep_or1(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
1036-
; SDISEL-LABEL: deep_or1:
1037-
; SDISEL: ; %bb.0:
1038-
; SDISEL-NEXT: cmp w2, #20
1039-
; SDISEL-NEXT: ccmp w2, #15, #4, ne
1040-
; SDISEL-NEXT: ccmp w0, #0, #4, eq
1041-
; SDISEL-NEXT: ccmp w1, #0, #4, ne
1042-
; SDISEL-NEXT: csel w0, w4, w5, ne
1043-
; SDISEL-NEXT: ret
1044-
;
1045-
; GISEL-LABEL: deep_or1:
1046-
; GISEL: ; %bb.0:
1047-
; GISEL-NEXT: mov w8, #15
1048-
; GISEL-NEXT: cmp w2, #20
1049-
; GISEL-NEXT: ccmp w2, w8, #4, ne
1050-
; GISEL-NEXT: ccmp w0, wzr, #4, eq
1051-
; GISEL-NEXT: ccmp w1, wzr, #4, ne
1052-
; GISEL-NEXT: csel w0, w4, w5, ne
1053-
; GISEL-NEXT: ret
1006+
; CHECK-LABEL: deep_or1:
1007+
; CHECK: ; %bb.0:
1008+
; CHECK-NEXT: cmp w2, #20
1009+
; CHECK-NEXT: ccmp w2, #15, #4, ne
1010+
; CHECK-NEXT: ccmp w0, #0, #4, eq
1011+
; CHECK-NEXT: ccmp w1, #0, #4, ne
1012+
; CHECK-NEXT: csel w0, w4, w5, ne
1013+
; CHECK-NEXT: ret
10541014
%c0 = icmp ne i32 %a0, 0
10551015
%c1 = icmp ne i32 %a1, 0
10561016
%c2 = icmp eq i32 %a2, 15
@@ -1065,24 +1025,14 @@ define i32 @deep_or1(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
10651025

10661026
; Variation of deep_or, we still need to implement the OR first though.
10671027
define i32 @deep_or2(i32 %a0, i32 %a1, i32 %a2, i32 %a3, i32 %x, i32 %y) {
1068-
; SDISEL-LABEL: deep_or2:
1069-
; SDISEL: ; %bb.0:
1070-
; SDISEL-NEXT: cmp w2, #20
1071-
; SDISEL-NEXT: ccmp w2, #15, #4, ne
1072-
; SDISEL-NEXT: ccmp w1, #0, #4, eq
1073-
; SDISEL-NEXT: ccmp w0, #0, #4, ne
1074-
; SDISEL-NEXT: csel w0, w4, w5, ne
1075-
; SDISEL-NEXT: ret
1076-
;
1077-
; GISEL-LABEL: deep_or2:
1078-
; GISEL: ; %bb.0:
1079-
; GISEL-NEXT: mov w8, #15
1080-
; GISEL-NEXT: cmp w2, #20
1081-
; GISEL-NEXT: ccmp w2, w8, #4, ne
1082-
; GISEL-NEXT: ccmp w1, wzr, #4, eq
1083-
; GISEL-NEXT: ccmp w0, wzr, #4, ne
1084-
; GISEL-NEXT: csel w0, w4, w5, ne
1085-
; GISEL-NEXT: ret
1028+
; CHECK-LABEL: deep_or2:
1029+
; CHECK: ; %bb.0:
1030+
; CHECK-NEXT: cmp w2, #20
1031+
; CHECK-NEXT: ccmp w2, #15, #4, ne
1032+
; CHECK-NEXT: ccmp w1, #0, #4, eq
1033+
; CHECK-NEXT: ccmp w0, #0, #4, ne
1034+
; CHECK-NEXT: csel w0, w4, w5, ne
1035+
; CHECK-NEXT: ret
10861036
%c0 = icmp ne i32 %a0, 0
10871037
%c1 = icmp ne i32 %a1, 0
10881038
%c2 = icmp eq i32 %a2, 15

0 commit comments

Comments
 (0)