[Bug middle-end/84747] alias analysis reports may-conflict for references to disjoint address spaces

2018-03-07 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84747

--- Comment #3 from Stefan M Freudenberger  ---
In this case I would have expected that TARGET_ADDR_SPACE_SUBSET_P will return
TRUE, as appropriate.

Granted, it would render my example invalid for x86.

[Bug c/84747] New: alias analysis reports may-conflict for references to disjoint address spaces

2018-03-07 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=84747

Bug ID: 84747
   Summary: alias analysis  reports may-conflict for references to
disjoint address spaces
   Product: gcc
   Version: 7.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: c
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stefan at reservoir dot com
  Target Milestone: ---

Created attachment 43584
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=43584=edit
patch to improve alias analysis for disjoint address spaces

For an out-of-tree target that supports address spaces the aliaser does not
report that references to distinct non-overlapping address spaces don’t
conflict. The following program shows this failure when compiled with gcc 7.3
and ‘–O’:

typedef int v4si __attribute__((__vector_size__(16)));

v4si
foo (__seg_gs v4si* ap, v4si* gp)
{
  *gp += (v4si){1,1,1,1};
  *ap = (v4si){1,2,3,4};
  return *gp;
}

To wit, the store ‘*ap =’ should not kill the available value of ‘*gp +=’ of
the preceding line, hence no reload of ‘*gp’ should be needed for the return.

The attached patch eliminates the load for the return, both in tree-ssa-alias.c
(ME) and alias.c (BE). The latter is included for completeness.

This target also supports some references to a special address space with some
side effects that cannot be described by the IR. We use intrinsics to perform
these operations. These intrinsics should not kill references to the generic
address space. To accomplish this, the attached patch also provides target
hooks to leave it to the target specific code to decide whether these
intrinsics conflict with other references. These hooks are not yet documented
since I wasn’t sure in which section they should be documented.

Finally, the patch includes a warning for conversions between pointers to
non-overlapping address spaces that are not known to be null pointers, as such
conversions are ill defined.

[Bug middle-end/80262] address space gets lost in memory access

2017-04-05 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80262

--- Comment #6 from Stefan M Freudenberger  ---
Created attachment 41134
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41134=edit
Modified source program that shows issue on x86_64.

I've modified my example (attached) to show the issue in x86_64, and tried it
on ToT, with the following results:

GNU C11 (GCC) version 7.0.1 20170330 (experimental) (x86_64-pc-linux-gnu)
compiled by GNU C version 7.0.1 20170330 (experimental), GMP version
6.1.2, MPFR version 3.1.5, MPC version 1.0.3, isl version none
GGC heuristics: --param ggc-min-expand=30 --param ggc-min-heapsize=4096
Compiler executable checksum: a526ee0d3a9f89b7e918be755c2fadee
bug5.c: In function ‘clearS2’:
bug5.c:23:1: internal compiler error: tree check: expected integer_cst, have
addr_space_convert_expr in decompose, at tree.h:5256
}
^
0xdebe6c tree_check_failed(tree_node const*, char const*, int, char const*,
...)
../../src/gcc-trunk/gcc/tree.c:9817
0x57b864 tree_check(tree_node const*, char const*, int, char const*, tree_code)
../../src/gcc-trunk/gcc/tree.h:3320
0x57b864 wi::int_traits::decompose(long*, unsigned int,
tree_node const*)
../../src/gcc-trunk/gcc/tree.h:5256
0xdf41aa wi::int_traits::decompose(long*, unsigned int,
tree_node const*)
../../src/gcc-trunk/gcc/tree.h:3254
0xdf41aa wide_int_ref_storage::wide_int_ref_storage(tree_node const* const&)
../../src/gcc-trunk/gcc/wide-int.h:967
0xdf41aa generic_wide_int::generic_wide_int(tree_node* const&)
../../src/gcc-trunk/gcc/wide-int.h:745
0xdf41aa mem_ref_offset(tree_node const*)
../../src/gcc-trunk/gcc/tree.c:4645
0xc4f131 indirect_refs_may_alias_p
../../src/gcc-trunk/gcc/tree-ssa-alias.c:1319
0xc519bc refs_may_alias_p_1(ao_ref*, ao_ref*, bool)
../../src/gcc-trunk/gcc/tree-ssa-alias.c:1536
0xd0cca5 vn_reference_lookup_3
../../src/gcc-trunk/gcc/tree-ssa-sccvn.c:1821
0xc54689 maybe_skip_until
../../src/gcc-trunk/gcc/tree-ssa-alias.c:2645
0xc54b64 get_continuation_for_phi_1
../../src/gcc-trunk/gcc/tree-ssa-alias.c:2686
0xc54b64 get_continuation_for_phi(gimple*, ao_ref*, unsigned int*,
bitmap_head**, bool, void* (*)(ao_ref*, tree_node*, void*, bool*), void*)
../../src/gcc-trunk/gcc/tree-ssa-alias.c:2777
0xc54e05 walk_non_aliased_vuses(ao_ref*, tree_node*, void* (*)(ao_ref*,
tree_node*, unsigned int, void*), void* (*)(ao_ref*, tree_node*, void*, bool*),
tree_node* (*)(tree_node*), void*)
../../src/gcc-trunk/gcc/tree-ssa-alias.c:2849
0xd0c189 vn_reference_lookup(tree_node*, tree_node*, vn_lookup_kind,
vn_reference_s**, bool)
../../src/gcc-trunk/gcc/tree-ssa-sccvn.c:2448
0xce15ab eliminate_dom_walker::before_dom_children(basic_block_def*)
../../src/gcc-trunk/gcc/tree-ssa-pre.c:4500
0x1244eca dom_walker::walk(basic_block_def*)
../../src/gcc-trunk/gcc/domwalk.c:265
0xce0181 eliminate
../../src/gcc-trunk/gcc/tree-ssa-pre.c:4773
0xce04c4 execute
../../src/gcc-trunk/gcc/tree-ssa-pre.c:5207
Please submit a full bug report,
with preprocessed source if appropriate.
Please include the complete backtrace with any bug report.
See  for instructions.

[Bug middle-end/80262] address space gets lost in memory access

2017-03-30 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80262

--- Comment #4 from Stefan M Freudenberger  ---
My original example involved a MEM with a constant offset, and yielded an ICE:

internal compiler error: tree check: expected integer_cst, have
addr_space_convert_expr in decompose, at tree.h

Maybe I misinterpreted what type to expect for the operands of the MEM, and
hence constructed a bad example. I'll try to come up with an example that shows
the ICE.

[Bug middle-end/80262] address space gets lost in memory access

2017-03-30 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80262

--- Comment #2 from Stefan M Freudenberger  ---
Created attachment 41088
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41088=edit
Output from -fdump-tree-esra

[Bug middle-end/80262] address space gets lost in memory access

2017-03-30 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80262

--- Comment #1 from Stefan M Freudenberger  ---
Created attachment 41087
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41087=edit
Output from -fdump-tree-forwprop1

[Bug middle-end/80262] New: address space gets lost in memory access

2017-03-30 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=80262

Bug ID: 80262
   Summary: address space gets lost in memory access
   Product: gcc
   Version: 6.3.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: middle-end
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stefan at reservoir dot com
  Target Milestone: ---

Created attachment 41086
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=41086=edit
The source program

For an out-of-tree target that supports address spaces the address space is
lost during early sra in the following example when compiled with -O3:

 cut 
typedef int v4si __attribute__ (( __vector_size__ (16) ));

typedef struct {
  v4si v;
} S1;
S1 clearS1() { S1 s1 = { 0 }; return s1; }

typedef struct {
  S1 s2[4];
} S2;
void initS2(__ea S2* p, int i) {
  p->s2[i] = clearS1();
}
 cut 

At the end of forwprop1, in initS2 there still is the reference to p->s2[i],
but when esra creates a replacement for the result value of the inlined
clearS1, the memory reference is rewritten dropping the address space (see the
attached dumps).

Of course, I may have introduced this bug with my changes, maybe someone with a
target that supports address spaces can confirm this problem?

The problem appears to be due to the type returned by reference_alias_ptr_type
in this case: it builds a pointer to the TYPE_MAIN_VARIANT, thus dropping the
address space qualifier. The following patch may solve this problem:

 cut 
--- orig_gcc-6.3.0/gcc/alias.c  2016-12-07 22:47:48.0 +
+++ gcc/gcc/alias.c 2017-03-29 13:42:15.192688629 +
@@ -784,7 +784,13 @@
   || TREE_CODE (t) == TARGET_MEM_REF)
 return TREE_TYPE (TREE_OPERAND (t, 1));
   else
-return build_pointer_type (TYPE_MAIN_VARIANT (TREE_TYPE (t)));
+{
+  addr_space_t as = TYPE_ADDR_SPACE (TREE_TYPE (t));
+  tree tem = TYPE_MAIN_VARIANT (TREE_TYPE (t));
+  if (!ADDR_SPACE_GENERIC_P (as))
+   tem = build_qualified_type (tem, ENCODE_QUAL_ADDR_SPACE (as));
+  return build_pointer_type (tem);
+}
 }

 /* Return whether the pointer-types T1 and T2 used to determine
 cut 

[Bug tree-optimization/79527] non-call-exceptions optimize attribute not propagated during inlining

2017-02-15 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79527

--- Comment #1 from Stefan M Freudenberger  ---
Created attachment 40745
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40745=edit
Output of -fdump-tree-einline-eh with -fnon-call-exceptions command line flag

[Bug tree-optimization/79527] New: non-call-exceptions optimize attribute not propagated during inlining

2017-02-15 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79527

Bug ID: 79527
   Summary: non-call-exceptions optimize attribute not propagated
during inlining
   Product: gcc
   Version: 5.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stefan at reservoir dot com
  Target Milestone: ---

Created attachment 40744
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40744=edit
Output of -fdump-tree-einline-eh without -fnon-call-exceptions command line
flag

The following program shows that the 'optimize (( "non-call-exceptions" ))'
attribute of "inner" is not propagated when this function is inlined into
"outer" and hence no exception region and landing pad is generated.

When "inner" is declared "inline" but not "always_inline", it is not inlined
and the resulting code is ok.

It also works when "-fnon-call-exceptions" is specified on the command line.

It seems safe to allow this since at the time of inlining the exception landing
pads have been generated; and they are correctly copied when the global flag is
set.

Here is the preprocessed program:

# 1 "inline.cpp"
# 1 ""
# 1 ""
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "" 2
# 1 "inline.cpp"
[[noreturn]] void my_exception_handler (void) noexcept;

inline __attribute__ (( __always_inline__ )) void
inner (int* x, int y)
__attribute__ (( __optimize__ ( "non-call-exceptions" ) ));

inline __attribute__ (( __always_inline__ )) void
inner (int* x, int y) {
  try {
*x = y;
  }
  catch (...) {
my_exception_handler ();
  }
}

extern void
outer (int* x, int y) {
  inner (x, y);
}

Compiled using:

g++ -v -save-temps -Wall -Wextra -std=gnu++14 -fdump-tree-einline-eh
-fnon-call-exceptions -O -S inline.ii
Using built-in specs.
COLLECT_GCC=g++
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-5 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-i386/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-i386
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-i386
--with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror
--with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=i686-linux-gnu
--host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4)
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-std=gnu++14'
'-fdump-tree-einline-eh' '-fnon-call-exceptions' '-O' '-S' '-shared-libgcc'
'-mtune=generic' '-march=i686'
 /usr/lib/gcc/i686-linux-gnu/5/cc1plus -fpreprocessed inline.ii -quiet
-dumpbase inline.ii -mtune=generic -march=i686 -auxbase inline -O -Wall -Wextra
-std=gnu++14 -version -fdump-tree-einline-eh -fnon-call-exceptions -o inline.s
-fstack-protector-strong -Wformat-security
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609
(i686-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR
version 3.1.4, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609
(i686-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR
version 3.1.4, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 427d6507e583781294a191f5962a1495
COMPILER_PATH=/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/5/../../../../lib/:/lib/i386-linux-gnu/:/lib/../lib/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/i686-linux-gnu/5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-std=gnu++14'
'-fdump-tree-einline-eh' '-fnon-call-exceptions' '-O' '-S' '-shared-libgcc'
'-mtune=

[Bug tree-optimization/78646] incorrect result type for pointer addition in slsr

2016-12-02 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78646

--- Comment #5 from Stefan M Freudenberger  ---
This is the revised patch:

-  add_expr = fold_build2 (POINTER_PLUS_EXPR, TREE_TYPE (c->base_expr),
+  add_expr = fold_build2 (POINTER_PLUS_EXPR, c->cand_type,
  c->base_expr, c->stride);

[Bug tree-optimization/78646] incorrect result type for pointer addition in slsr

2016-12-02 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78646

--- Comment #4 from Stefan M Freudenberger  ---
I guess there wouldn't be an issue if it were a reference type. However, there
is an issue with the incorrect alignment for the object type.

[Bug tree-optimization/78646] incorrect result type for pointer addition in slsr

2016-12-02 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78646

--- Comment #2 from Stefan M Freudenberger  ---
It's not an ICE on x86, but the dump shows the incorrect pointer type.

Can I assert that the cand_type is a pointer and not a reference?

[Bug tree-optimization/78646] New: incorrect result type for pointer addition in slsr

2016-12-02 Thread stefan at reservoir dot com
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=78646

Bug ID: 78646
   Summary: incorrect result type for pointer addition in slsr
   Product: gcc
   Version: 5.4.0
Status: UNCONFIRMED
  Severity: normal
  Priority: P3
 Component: tree-optimization
  Assignee: unassigned at gcc dot gnu.org
  Reporter: stefan at reservoir dot com
  Target Milestone: ---

Created attachment 40225
  --> https://gcc.gnu.org/bugzilla/attachment.cgi?id=40225=edit
output of -fdump-tree-slsr

In the program below, struct A is 64-bit aligned and struct B is 128-bit
aligned. An array of struct A in part of struct B.

When the array in B is accessed with a variable index, slsr computes the
pointer to the array element with the incorrect type 'struct B *' rather than
'struct A *'.

On my out-of-tree target, this results in incorrect code being generated; on
x86 I can only show the issue when looking at the debug output.

In the attached dump, the type of _8 and _14 is 'struct B *' but I would expect
them to have type 'struct A *'.

Here is the preprocessed program:

# 1 "bug.cpp"
# 1 ""
# 1 ""
# 1 "/usr/include/stdc-predef.h" 1 3 4
# 1 "" 2
# 1 "bug.cpp"
typedef int v4si __attribute__((vector_size(16)));
typedef int v2si __attribute__((vector_size(8)));

int __builtin_foo(int, int, int);

template <typename, typename> struct A;
template <> struct alignas(v2si) A<int, int> {
  int _a;
  int _b;
};

template  T foo(T a, A<int, int> , int) {
  return __builtin_foo(a, b._a, b._b);
}

template  T foo(A<int, int> , T b, int c) {
  return foo(b, a, c);
}

struct alignas(v4si) B {
  struct {
A<int, int> ara[16];
  };
  int bar(int, int);
};

int B::bar(int i, int a) {
  return foo(ara[i], a, 1);
}


Compiled using:

g++ -v -save-temps -Wall -Wextra -std=gnu++14 -fdump-tree-slsr
-fdump-tree-optimized -O -S bug.ii
Using built-in specs.
COLLECT_GCC=g++
Target: i686-linux-gnu
Configured with: ../src/configure -v --with-pkgversion='Ubuntu
5.4.0-6ubuntu1~16.04.4' --with-bugurl=file:///usr/share/doc/gcc-5/README.Bugs
--enable-languages=c,ada,c++,java,go,d,fortran,objc,obj-c++ --prefix=/usr
--program-suffix=-5 --enable-shared --enable-linker-build-id
--libexecdir=/usr/lib --without-included-gettext --enable-threads=posix
--libdir=/usr/lib --enable-nls --with-sysroot=/ --enable-clocale=gnu
--enable-libstdcxx-debug --enable-libstdcxx-time=yes
--with-default-libstdcxx-abi=new --enable-gnu-unique-object
--disable-vtable-verify --enable-libmpx --enable-plugin --with-system-zlib
--disable-browser-plugin --enable-java-awt=gtk --enable-gtk-cairo
--with-java-home=/usr/lib/jvm/java-1.5.0-gcj-5-i386/jre --enable-java-home
--with-jvm-root-dir=/usr/lib/jvm/java-1.5.0-gcj-5-i386
--with-jvm-jar-dir=/usr/lib/jvm-exports/java-1.5.0-gcj-5-i386
--with-arch-directory=i386 --with-ecj-jar=/usr/share/java/eclipse-ecj.jar
--enable-objc-gc --enable-targets=all --enable-multiarch --disable-werror
--with-arch-32=i686 --with-multilib-list=m32,m64,mx32 --enable-multilib
--with-tune=generic --enable-checking=release --build=i686-linux-gnu
--host=i686-linux-gnu --target=i686-linux-gnu
Thread model: posix
gcc version 5.4.0 20160609 (Ubuntu 5.4.0-6ubuntu1~16.04.4) 
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-std=gnu++14'
'-fdump-tree-slsr' '-fdump-tree-optimized' '-O' '-S' '-shared-libgcc'
'-mtune=generic' '-march=i686'
 /usr/lib/gcc/i686-linux-gnu/5/cc1plus -fpreprocessed bug.ii -quiet -dumpbase
bug.ii -mtune=generic -march=i686 -auxbase bug -O -Wall -Wextra -std=gnu++14
-version -fdump-tree-slsr -fdump-tree-optimized -o bug.s
-fstack-protector-strong -Wformat-security
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609
(i686-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR
version 3.1.4, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
GNU C++14 (Ubuntu 5.4.0-6ubuntu1~16.04.4) version 5.4.0 20160609
(i686-linux-gnu)
compiled by GNU C version 5.4.0 20160609, GMP version 6.1.0, MPFR
version 3.1.4, MPC version 1.0.3
GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
Compiler executable checksum: 427d6507e583781294a191f5962a1495
COMPILER_PATH=/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/
LIBRARY_PATH=/usr/lib/gcc/i686-linux-gnu/5/:/usr/lib/gcc/i686-linux-gnu/5/../../../i386-linux-gnu/:/usr/lib/gcc/i686-linux-gnu/5/../../../../lib/:/lib/i386-linux-gnu/:/lib/../lib/:/usr/lib/i386-linux-gnu/:/usr/lib/../lib/:/usr/lib/gcc/i686-linux-gnu/5/../../../:/lib/:/usr/lib/
COLLECT_GCC_OPTIONS='-v' '-save-temps' '-Wall' '-Wextra' '-std=gnu++14'
'-fdump-tree-slsr' '-fdump-tree-optimized' '-O' '-S' '-shared-libgcc'
'-mtune=generic' '-march=i686'

Here is a possible sol