[LLVMbugs] [Bug 1567] NEW: Testcase 'CFrontend/exact-div-expr.c' Fails (sometimes) on 64bit

bugzilla-daemon at cs.uiuc.edu bugzilla-daemon at cs.uiuc.edu
Mon Jul 23 15:29:46 PDT 2007


http://llvm.org/bugs/show_bug.cgi?id=1567

           Summary: Testcase 'CFrontend/exact-div-expr.c' Fails (sometimes)
                    on 64bit
           Product: Test Suite
           Version: trunk
          Platform: PC
        OS/Version: Linux
            Status: NEW
          Severity: normal
          Priority: P2
         Component: DejaGNU
        AssignedTo: chandlerc at gmail.com
        ReportedBy: chandlerc at gmail.com


Sometimes, but not always, the CFrontend/exact-div-expr test fails. This is due
to a very bizarre confluence of 64bit words and optimization passes enabled by
default in llvm-gcc.

The test case is ensuring that a divide by a constant power of 2 is reduced to
an arithmetic shift right. To test it, pointer arithmetic is used, as this is
the most common place it is used.

The test case:
----
int test(int *A, int *B) {
  return A-B;
}
----

The 32bit .ll:
----
; ModuleID = 'CFrontend/exact-div-expr.c'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
target triple = "x86_64-pc-linux-gnu"

define i32 @test(i32* %A, i32* %B) {
entry:
  %tmp12 = ptrtoint i32* %A to i32        ; <i32> [#uses=1]
  %tmp34 = ptrtoint i32* %B to i32        ; <i32> [#uses=1]
  %tmp5 = sub i32 %tmp12, %tmp34          ; <i32> [#uses=1]
  %tmp6 = ashr i32 %tmp5, 2               ; <i32> [#uses=1]
  ret i32 %tmp6
}
----

The 64-bit .ll:
----
; ModuleID = 'CFrontend/exact-div-expr.c'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64"
target triple = "x86_64-pc-linux-gnu"

define i32 @test(i32* %A, i32* %B) {
entry:
  %tmp12 = ptrtoint i32* %A to i64        ; <i64> [#uses=1]
  %tmp34 = ptrtoint i32* %B to i64        ; <i64> [#uses=1]
  %tmp5 = sub i64 %tmp12, %tmp34          ; <i64> [#uses=1]
  %tmp610 = lshr i64 %tmp5, 2             ; <i64> [#uses=1]
  %tmp67 = trunc i64 %tmp610 to i32       ; <i32> [#uses=1]
  ret i32 %tmp67
}
----

Note that the "ashr" has turned into an "lshr". This is valid because of the
following "trunc" which removes any non-signed bits shifted into the left
32bits. This is a classic "int is not a word, pointers are words" problem with
C. I Think the following test case will compile correctly and generate the
desired code on any architecture:

proposed new test case:
----
int *test(int *A, int *B) {
  return A-B;
}
----

This should keep the same bitwidth on all operations on any architecture, and
not suffer from any loss of precisions that allow unexpected optimizations to
mess up the pattern matching on the code.

-Chandler



------- You are receiving this mail because: -------
You are on the CC list for the bug, or are watching someone who is.



More information about the llvm-bugs mailing list