Skip to content
This repository was archived by the owner on Sep 2, 2018. It is now read-only.

Commit 1d0dc0f

Browse files
author
Chad Rosier
committed
[AArch64] Avoid materializing constant 1 when generating cneg instructions.
Instead of cmp w0, #1 orr w8, wzr, #0x1 cneg w0, w8, ne we now generate cmp w0, #1 csinv w0, w0, wzr, eq PR28965 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@285217 91177308-0d34-0410-b5e6-96231b3b80d8
1 parent 9eeea0a commit 1d0dc0f

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lib/Target/AArch64/AArch64ISelLowering.cpp

+13-2
Original file line numberDiff line numberDiff line change
@@ -4054,8 +4054,9 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
40544054

40554055
// Avoid materializing a constant when possible by reusing a known value in
40564056
// a register. However, don't perform this optimization if the known value
4057-
// is one, zero or negative one. We can always materialize these values
4058-
// using CSINC, CSEL and CSINV with wzr/xzr as the FVal, respectively.
4057+
// is one, zero or negative one in the case of a CSEL. We can always
4058+
// materialize these values using CSINC, CSEL and CSINV with wzr/xzr as the
4059+
// FVal, respectively.
40594060
ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
40604061
if (Opcode == AArch64ISD::CSEL && RHSVal && !RHSVal->isOne() &&
40614062
!RHSVal->isNullValue() && !RHSVal->isAllOnesValue()) {
@@ -4066,6 +4067,16 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
40664067
TVal = LHS;
40674068
else if (CFVal && CFVal == RHSVal && AArch64CC == AArch64CC::NE)
40684069
FVal = LHS;
4070+
} else if (Opcode == AArch64ISD::CSNEG && RHSVal && RHSVal->isOne()) {
4071+
assert (CTVal && CFVal && "Expected constant operands for CSNEG.");
4072+
// Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to
4073+
// avoid materializing C.
4074+
AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
4075+
if (CTVal == RHSVal && AArch64CC == AArch64CC::EQ) {
4076+
Opcode = AArch64ISD::CSINV;
4077+
TVal = LHS;
4078+
FVal = DAG.getConstant(0, dl, FVal.getValueType());
4079+
}
40694080
}
40704081

40714082
SDValue CCVal;

test/CodeGen/AArch64/cond-sel-value-prop.ll

+11
Original file line numberDiff line numberDiff line change
@@ -97,3 +97,14 @@ define i64 @test9(i64 %x) {
9797
%res = select i1 %cmp, i64 7, i64 -1
9898
ret i64 %res
9999
}
100+
101+
; Rather than use a CNEG, use a CSINV to transform "a == 1 ? 1 : -1" to
102+
; "a == 1 ? a : -1" to avoid materializing a constant.
103+
; CHECK-LABEL: test10:
104+
; CHECK: cmp w[[REG:[0-9]]], #1
105+
; CHECK: cneg w0, w[[REG]], ne
106+
define i32 @test10(i32 %x) {
107+
%cmp = icmp eq i32 %x, 1
108+
%res = select i1 %cmp, i32 1, i32 -1
109+
ret i32 %res
110+
}

0 commit comments

Comments
 (0)