Intel® C++ Compiler
Community support and assistance for creating C++ code that runs on platforms based on Intel® processors.

miscompilation of int16_t division

Matthias_Kretz
New Contributor I
582 Views

Testcase:
[cpp]#include <iostream>

struct A
{
    short d[8];
    A() {}
    A(short a) {}
    A operator/(short x) const
    {
        A r;
        r.d[0] = d[0] / x;
        r.d[1] = d[1] / x;
        r.d[2] = d[2] / x;
        r.d[3] = d[3] / x;
        return r;
    }
};

A tmp;

int main()
{
    short divisor = 2;
    for (short scalar = -32768; scalar < -32700; scalar += 32) {
        A vector(scalar);
        tmp = vector / divisor;
        std::cout << scalar << " / " << divisor << " = " << scalar / divisor << "\n";
    }
}[/cpp]

Compile without any extra flags for either -m32 or -m64 on Linux. This is what I get then:
[plain]-32768 / 2 = 16384
-32736 / 2 = 16400
-32704 / 2 = 16416[/plain]

The expected output is:
[plain]-32768 / 2 = -16384
-32736 / 2 = -16368
-32704 / 2 = -16352[/plain]

0 Kudos
8 Replies
MalReddy_Y_Intel
Employee
582 Views

Hi Mathias,

This seems  issue during the IPO,IL0 optimization phase in the presence of -O2,-O3 optimization switches.

Snippet of compilation optimization report at which incorrect results occur.

{{{

Routine _ZN1AC1Ev (1), (IP Summary), optimizing.

Routine _ZN1AC1Es (2), (IP Summary), optimizing.

Routine _ZNK1AdvEs (3), (IP Summary), optimizing.

Routine main (4), (IP Summary), optimizing.

Routine __sti__$E (5), (IP Summary), optimizing.

Routine __sti__tmp (6), (IP Summary), optimizing.

(IP optimizations) (7), optimizing.

Routine main (8), (IP Compile), optimizing.

Routine __sti__$E (9), (IP Compile), optimizing.

DOING [IPO] IP Const Prop Direct  (1)

DOING [IPO] DV Uplevel Subst  (2)

DOING [IPO] IP Const Prop Indirect  (3)

DOING [IL0] kstaticize locals  (4)

DOING [IL0] Substitution  (5)

DOING [PAROPT] PAROPT IL0 Restructuring  (6)

DOING [IL0] sincos promotion  (7)

DOING [IL0] IL0_PEEP_IDivs  (8)

DOING [IL0] Complex Lowering  (9) (last opt)

AVOIDING [IL0] SIMP  (10)

AVOIDING [IL0] il0_norm var replacement  (11)

}}}

I can also reproduce the issue, I will log defect and let you know more details once it is resolved.

Thanks for useful testcase.

Reddy

0 Kudos
Matthias_Kretz
New Contributor I
582 Views

Thanks for taking it up. Do you have an idea for a workaround? This code appears in one of my unit test to create the reference data - my unit test fails because the reference is wrong...

0 Kudos
MalReddy_Y_Intel
Employee
582 Views

Current workaround can be compiling the source with -O1 or -O0 flag.

0 Kudos
Matthias_Kretz
New Contributor I
582 Views

That's not an acceptable workaround. It would make the test significantly weaker. I need to be sure that everything works as expected at -O3.

0 Kudos
Shenghong_G_Intel
582 Views

You can add "#pragma optimize("", on|off)" to disable the part of code with optimization bug, and you can still use -O3 to compile other parts of code and run your testing.

some code...

#pragma optimize("", off)

this code with issues at O3

#pragma optimize("", on)

some other code...

Thanks,

Shenghong

0 Kudos
MalReddy_Y_Intel
Employee
582 Views

Hi,

Hi,

This is a signed overflow issue with loop normalization, Its implemented and targeted for

upcoming 14.0 branch (Ref Defect:DPD200249862 ).

Regards,

Reddy

0 Kudos
bernaske
New Contributor I
582 Views

Hi

i compiled the sample with

icc (ICC) 14.0.1 20131008
Copyright (C) 1985-2013 Intel Corporation.  All rights reserved.

under openSUSE Linux 12.3 , 13.1 and 13.2 ( Factory) the same problem works only correct with -O1 as option

does not correct work with -O3 -m64, only with -O1 -m64

regards

Franz

 

 

 

 

0 Kudos
MalReddy_Y_Intel
Employee
582 Views

This issue is fixed in latest 14.0 compiler, FYI.

Thanks,

Reddy

 

0 Kudos
Reply