Opened 9 years ago

Closed 9 years ago

Last modified 8 years ago

#8695 closed Bugs (worksforme)

boost::polygon faillure with optimizations enabled on g++-4.7.2

Reported by: hodevel@… Owned by: Andrii Sydorchuk
Milestone: To Be Determined Component: polygon
Version: Boost 1.53.0 Severity: Problem
Keywords: Cc:

Description

Following program does not return same results depending on optimization level. When using -00 with g++-4.7.2, area is 100 (good result). When using -02, area is 0 (bad result).

Other compilation options: -Wall -std=c++0x -g

#include <iostream>
#include <cstdio>
#include <boost/polygon/polygon.hpp>


typedef boost::polygon::point_data<int> point_t;
typedef boost::polygon::polygon_data<int> poly_t;
typedef boost::polygon::polygon_set_data<int> poly_set_t;

int main(int argc, char** argv)
{
	using namespace boost::polygon::operators;

	std::list<point_t> points =
	{
		point_t(0, 0),
		point_t(10, 0),
		point_t(10, 10),
		point_t(0, 10)
	};

	poly_t poly;
	poly.set(points.begin(), points.end());

	poly_set_t poly_set;
	poly_set |= poly;

	std::cout << "poly_set area: " << boost::polygon::area(poly_set)
		<< std::endl;

	return 0;
}

Attachments (1)

8695.patch (2.8 KB ) - added by Andrii Sydorchuk 8 years ago.

Download all attachments as: .zip

Change History (13)

comment:1 by Andrii Sydorchuk, 9 years ago

Owner: changed from Lucanus Simonson to Andrii Sydorchuk
Status: newassigned

comment:2 by Andrii Sydorchuk, 9 years ago

Hi,

I've tried to reproduce the given behavior with g++ 4.7.3, however got correct output.

[CLI] g++ -I ~/Downloads/boost_1_53_0 -Wall -std=c++0x -g -O2 -v main.cpp && ./a.out
[OUTPUT] poly_set area: 100

We've got a few other reports, that state some flakiness with -O2 flag for g++ 4.7.2.

Would it be feasible for you to upgrade to 4.7.3 and verify the failure?

comment:3 by hodevel@…, 9 years ago

Hi,

Compiled gcc-4.7.3 on the same machine to test. Got no problem with gcc-4.7.3 - just like you.

Using gdb is not very easy since optimizations are enabled. Is there any other test I can run to find what's wrong ? Maybe this is more a bug of gcc rather than a bug in boost polygon...

comment:4 by Andrii Sydorchuk, 9 years ago

Resolution: worksforme
Status: assignedclosed

I didn't have enough time to go deeper in this issue. So far I was not able to reproduce it, thus marking it as resolved. Potentially the issue here might be with the snap-rounding modes used by the Polygon. If that's the case the issue will be a duplicate of the ticket #6063.

comment:5 by aar@…, 8 years ago

Hello, get_trapezoids() is affected too, and I can reproduce the issue on any Debian Wheezy machine, since that distro uses 4.7.2. It looks like the gcc issue might be http://gcc.gnu.org/bugzilla/show_bug.cgi?id=56125 or http://gcc.gnu.org/bugzilla/show_bug.cgi?id=54767

I think this needs to be reopened and investigated, and some macros need to be added to workaround the issue if 4.7.0, 4.7.1 or 4.7.2 is detected. While upgrading to 4.7.3 makes the problem disappear, the great popularity of gcc 4.7.2 (thanks to Debian Wheezy) raises the need for a built-in workaround IMHO.

comment:6 by aar@…, 8 years ago

What about adding this to the relevant Boost.Polygon file(s):

#pragma GCC optimize ("O1")

wrapped in a conditional check for GCC version? Would the maintainers accept such a patch?

comment:7 by Andrii Sydorchuk, 8 years ago

Thank you for your email aar.
I would prefer to avoid applying such a fix without understanding the actual reason of the issue.
I was able to reproduce the behavior on ARMv6, Arch OS, g++ 4.7.2 with the following compilation prompt:
g++ -O2 main.cpp -I ../../boost/libs/polygon -std=c++11
Going to investigate.

comment:8 by aar@…, 8 years ago

Thank you asydorchuk for investigating. Maybe the GCC bugs I linked can give hints about the code patterns to look for?

comment:9 by Andrii Sydorchuk, 8 years ago

Those are definitely a good references.
I've also found the following report: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=60766.

comment:10 by Andrii Sydorchuk, 8 years ago

I've found the defect in the optimizer. Only one edge (instead of four) is inserted into the resulting polygon_data_set inside the polygon_set_data.hpp:insert_vertex_sequence call.

Using binary search I've figured out, that this behavior is caused by the following g++ compilation option: -f-inline-small-functions.

It would be great if you could confirm that adding flag -fno-inline-small-functions to your prompt fixes the issue with trapezoids.

Polygon code is in places quite convoluted. I rewrote insert_vertex_sequence so that it's more readable for humans and less confusing for compiler. Please find the patch attached. It will be automatically released with the next version of Boost.

by Andrii Sydorchuk, 8 years ago

Attachment: 8695.patch added

comment:11 by aar@…, 8 years ago

Hi asydorchuk, sorry for the late reply. I can confirm that the OP code snippet works for me when I compile it with: -O3 -fno-inline-small-functions I also confirm that my trapezoid code works correctly if I compile with -fno-inline-small-functions -O3 (unfortunately my toolchain does not let me append anything after -O3 but luckily enough -f options take precedence over -O regardless of their position).

comment:12 by Andrii Sydorchuk, 8 years ago

Glad to hear. I would assume that 8695 patch will also fix the issue, even without using -fno-inline-small-functions flag.

Note: See TracTickets for help on using tickets.