Skip to content

Commit c865723

Browse files
committed
[AArch64] Have isel just do neg directly
This means we do not have to rely on register coalescing to fix this, which matches gcc outputting things like neg on -O0
1 parent 979aca0 commit c865723

File tree

2 files changed

+14
-2
lines changed

2 files changed

+14
-2
lines changed

llvm/lib/Target/AArch64/AArch64FastISel.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1201,6 +1201,19 @@ Register AArch64FastISel::emitAddSub(bool UseAdd, MVT RetVT, const Value *LHS,
12011201
SI->getOpcode() == Instruction::AShr )
12021202
std::swap(LHS, RHS);
12031203

1204+
// Special case: sub 0, x -> neg x (use zero register directly)
1205+
if (!UseAdd && isa<Constant>(LHS) && cast<Constant>(LHS)->isNullValue()) {
1206+
Register RHSReg = getRegForValue(RHS);
1207+
if (!RHSReg)
1208+
return Register();
1209+
1210+
if (NeedExtend)
1211+
RHSReg = emitIntExt(SrcVT, RHSReg, RetVT, IsZExt);
1212+
1213+
Register ZeroReg = RetVT == MVT::i64 ? AArch64::XZR : AArch64::WZR;
1214+
return emitAddSub_rr(UseAdd, RetVT, ZeroReg, RHSReg, SetFlags, WantResult);
1215+
}
1216+
12041217
Register LHSReg = getRegForValue(LHS);
12051218
if (!LHSReg)
12061219
return Register();

llvm/test/CodeGen/AArch64/instruct-neg.ll

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@
44
define i32 @negb(i32 %b) {
55
; CHECK-LABEL: negb:
66
; CHECK: // %bb.0:
7-
; CHECK-NEXT: mov w8, wzr
8-
; CHECK-NEXT: sub w0, w8, w0
7+
; CHECK-NEXT: neg w0, w0
98
; CHECK-NEXT: ret
109
%sub = sub nsw i32 0, %b
1110
ret i32 %sub

0 commit comments

Comments
 (0)