mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2025-01-31 20:51:52 +01:00
[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 llvm-svn: 285217
This commit is contained in:
parent
bc67d8a523
commit
c0750fd641
@ -4054,8 +4054,9 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
|
||||
|
||||
// Avoid materializing a constant when possible by reusing a known value in
|
||||
// a register. However, don't perform this optimization if the known value
|
||||
// is one, zero or negative one. We can always materialize these values
|
||||
// using CSINC, CSEL and CSINV with wzr/xzr as the FVal, respectively.
|
||||
// is one, zero or negative one in the case of a CSEL. We can always
|
||||
// materialize these values using CSINC, CSEL and CSINV with wzr/xzr as the
|
||||
// FVal, respectively.
|
||||
ConstantSDNode *RHSVal = dyn_cast<ConstantSDNode>(RHS);
|
||||
if (Opcode == AArch64ISD::CSEL && RHSVal && !RHSVal->isOne() &&
|
||||
!RHSVal->isNullValue() && !RHSVal->isAllOnesValue()) {
|
||||
@ -4066,6 +4067,16 @@ SDValue AArch64TargetLowering::LowerSELECT_CC(ISD::CondCode CC, SDValue LHS,
|
||||
TVal = LHS;
|
||||
else if (CFVal && CFVal == RHSVal && AArch64CC == AArch64CC::NE)
|
||||
FVal = LHS;
|
||||
} else if (Opcode == AArch64ISD::CSNEG && RHSVal && RHSVal->isOne()) {
|
||||
assert (CTVal && CFVal && "Expected constant operands for CSNEG.");
|
||||
// Use a CSINV to transform "a == C ? 1 : -1" to "a == C ? a : -1" to
|
||||
// avoid materializing C.
|
||||
AArch64CC::CondCode AArch64CC = changeIntCCToAArch64CC(CC);
|
||||
if (CTVal == RHSVal && AArch64CC == AArch64CC::EQ) {
|
||||
Opcode = AArch64ISD::CSINV;
|
||||
TVal = LHS;
|
||||
FVal = DAG.getConstant(0, dl, FVal.getValueType());
|
||||
}
|
||||
}
|
||||
|
||||
SDValue CCVal;
|
||||
|
@ -97,3 +97,14 @@ define i64 @test9(i64 %x) {
|
||||
%res = select i1 %cmp, i64 7, i64 -1
|
||||
ret i64 %res
|
||||
}
|
||||
|
||||
; Rather than use a CNEG, use a CSINV to transform "a == 1 ? 1 : -1" to
|
||||
; "a == 1 ? a : -1" to avoid materializing a constant.
|
||||
; CHECK-LABEL: test10:
|
||||
; CHECK: cmp w[[REG:[0-9]]], #1
|
||||
; CHECK: cneg w0, w[[REG]], ne
|
||||
define i32 @test10(i32 %x) {
|
||||
%cmp = icmp eq i32 %x, 1
|
||||
%res = select i1 %cmp, i32 1, i32 -1
|
||||
ret i32 %res
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user