llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.04k stars 11.98k forks source link

[AArch64] Missed CMN opportunities #32833

Open llvmbot opened 7 years ago

llvmbot commented 7 years ago
Bugzilla Link 33486
Version trunk
OS Linux
Reporter LLVM Bugzilla Contributor
CC @Arnaud-de-Grandmaison-ARM

Extended Description

Tests: bool test1(int a, int b) { return (a + b) == 0; } bool test2(int a, int b) { return (a + b) != 0; }

Clang currently generates: test1: // @​test1 // BB#0: // %entry neg w8, w1 cmp w8, w0 cset w0, eq ret test2: // @​test2 // BB#0: // %entry neg w8, w1 cmp w8, w0 cset w0, ne ret

However, we should generate: test1: // @​test1 // BB#0: // %entry cmn w0, w1 cset w0, eq ret test2: // @​test2 // BB#0: // %entry cmn w0, w1 cset w0, ne ret

Reassociation will canonicalizes to these tests to 0-x == y and 0-x != y. And then for X86 a DAG combine will covert these back to x+y == 0 and x+y != 0, respectively.

Here's a patch for AArch64 that is a straight cut and paste from X86 to AArch64: diff --git a/lib/Target/AArch64/AArch64ISelLowering.cpp b/lib/Target/AArch64/AArch64ISelLowering.cpp index 083ca21..8286838 100644 --- a/lib/Target/AArch64/AArch64ISelLowering.cpp +++ b/lib/Target/AArch64/AArch64ISelLowering.cpp @@ -545,6 +545,7 @@ AArch64TargetLowering::AArch64TargetLowering(const TargetMachine &TM,

setTargetDAGCombine(ISD::MUL);

@@ -10204,6 +10205,34 @@ static SDValue performNVCASTCombine(SDNode *N) { return SDValue(); }

+static SDValue performSetCCCombine(SDNode *N, SelectionDAG &DAG) {

The above patch will fix the problem, but I'm not sure it's the best solution and it doesn't impact any of the workloads I care about. Therefore, I'm not interested in pursuing this further, but figured I'd file a bug..

Arnaud-de-Grandmaison-ARM commented 6 years ago

Changing to confirmed as this can be reproduced with ToT as of today : r346643