LLVM Bugzilla is read-only and represents the historical archive of all LLVM issues filled before November 26, 2021. Use github to submit LLVM bugs

Bug 1510 - xor-inferring optimizations would be nice
Summary: xor-inferring optimizations would be nice
Status: RESOLVED FIXED
Alias: None
Product: libraries
Classification: Unclassified
Component: Scalar Optimizations (show other bugs)
Version: trunk
Hardware: Macintosh MacOS X
: P enhancement
Assignee: Chris Lattner
URL:
Keywords: code-quality
Depends on:
Blocks:
 
Reported: 2007-06-15 00:21 PDT by Duraid Madina
Modified: 2010-02-22 12:40 PST (History)
1 user (show)

See Also:
Fixed By Commit(s):


Attachments
this module is really just doing an xor (316 bytes, application/octet-stream)
2007-06-15 00:37 PDT, Duraid Madina
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Duraid Madina 2007-06-15 00:21:56 PDT
we don't currently infer that

~( ~(a|b) | (a&b) ) -> a^b

and similar, e.g. ~(~a & ~b) & ~(a&b) -> a^b
Comment 1 Duraid Madina 2007-06-15 00:30:38 PDT
Compile this with llvm-gcc:

unsigned int *a, *b;

void joy(void) {
   a[20] = ~(~(a[10]|b[10]) | (a[10]&b[10]));
}

and you get:

define void @joy() {
entry:
        %tmp = load i32** @a            ; <i32*> [#uses=2]
        %tmp2 = getelementptr i32* %tmp, i32 10         ; <i32*> [#uses=1]
        %tmp3 = load i32* %tmp2         ; <i32> [#uses=2]
        %tmp4 = load i32** @b           ; <i32*> [#uses=1]
        %tmp5 = getelementptr i32* %tmp4, i32 10                ; <i32*> [#uses=1]
        %tmp6 = load i32* %tmp5         ; <i32> [#uses=2]
        %tmp7 = or i32 %tmp6, %tmp3             ; <i32> [#uses=1]
        %tmp7not = xor i32 %tmp7, -1            ; <i32> [#uses=1]
        %tmp14 = and i32 %tmp6, %tmp3           ; <i32> [#uses=1]
        %tmp15 = or i32 %tmp14, %tmp7not                ; <i32> [#uses=1]
        %tmp15not = xor i32 %tmp15, -1          ; <i32> [#uses=1]
        %tmp16 = getelementptr i32* %tmp, i32 20                ; <i32*> [#uses=1]
        store i32 %tmp15not, i32* %tmp16
        ret void
}


it could just use xor?
Comment 2 Duraid Madina 2007-06-15 00:37:16 PDT
Created attachment 1011 [details]
this module is really just doing an xor
Comment 3 Chris Lattner 2007-06-15 01:01:04 PDT
Here's a C vector example:

typedef unsigned __attribute__((vector_size(16))) vu;


vu test1(vu a, vu b) {
   return ~(~(a|b) | (a&b));
}

vu test2(vu a, vu b) {
   return (a|b) & ~(a&b);
}
Comment 4 Chris Lattner 2007-06-15 01:26:19 PDT
Implemented.  There are many patches to this, the primary ones being:
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070611/050487.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070611/050489.html
http://lists.cs.uiuc.edu/pipermail/llvm-commits/Week-of-Mon-20070611/050495.html

Testcase here: Transforms/InstCombine/and-or-not.ll

This shrunk Duraid's nasty example from 32K lines of x86-64 .s file to 23k lines.

-Chris