[LLVMbugs] [Bug 3101] New: Instcombine promotes i32 mul to i64 mul
bugzilla-daemon at cs.uiuc.edu
bugzilla-daemon at cs.uiuc.edu
Wed Nov 19 12:13:15 PST 2008
http://llvm.org/bugs/show_bug.cgi?id=3101
Summary: Instcombine promotes i32 mul to i64 mul
Product: libraries
Version: trunk
Platform: PC
OS/Version: Linux
Status: NEW
Severity: normal
Priority: P2
Component: Scalar Optimizations
AssignedTo: unassignedbugs at nondot.org
ReportedBy: tilmann.scheller at googlemail.com
CC: llvmbugs at cs.uiuc.edu
Translating the following snippet into LLVM IR on x86-64
long mul(long a, long b)
{
return ((int) a) * ((int) b);
}
with llvm-gcc -O0 results in the following code:
; ModuleID = 'mul.bc'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"
define i64 @mul(i64 %a, i64 %b) nounwind {
entry:
%a_addr = alloca i64 ; <i64*> [#uses=2]
%b_addr = alloca i64 ; <i64*> [#uses=2]
%retval = alloca i64 ; <i64*> [#uses=2]
%0 = alloca i64 ; <i64*> [#uses=2]
%"alloca point" = bitcast i32 0 to i32 ; <i32> [#uses=0]
store i64 %a, i64* %a_addr
store i64 %b, i64* %b_addr
%1 = load i64* %a_addr, align 8 ; <i64> [#uses=1]
%2 = trunc i64 %1 to i32 ; <i32> [#uses=1]
%3 = load i64* %b_addr, align 8 ; <i64> [#uses=1]
%4 = trunc i64 %3 to i32 ; <i32> [#uses=1]
%5 = mul i32 %2, %4 ; <i32> [#uses=1]
%6 = sext i32 %5 to i64 ; <i64> [#uses=1]
store i64 %6, i64* %0, align 8
%7 = load i64* %0, align 8 ; <i64> [#uses=1]
store i64 %7, i64* %retval, align 8
br label %return
return: ; preds = %entry
%retval1 = load i64* %retval ; <i64> [#uses=1]
ret i64 %retval1
}
Running opt -instcombine on this results in the following code:
; ModuleID = 'mulopt.bc'
target datalayout =
"e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128"
target triple = "x86_64-unknown-linux-gnu"
define i64 @mul(i64 %a, i64 %b) nounwind {
entry:
%retval = alloca i64 ; <i64*> [#uses=2]
%0 = mul i64 %a, %b ; <i64> [#uses=1]
%1 = trunc i64 %0 to i32 ; <i32> [#uses=1]
%2 = sext i32 %1 to i64 ; <i64> [#uses=1]
store i64 %2, i64* %retval, align 8
br label %return
return: ; preds = %entry
%retval1 = load i64* %retval ; <i64> [#uses=1]
ret i64 %retval1
}
Obviously the generated code is not incorrect, but it likely results in less
efficient code on targets without a native 64-bit multiplication instruction.
As the CellSPU does not have such a native 64-bit multiplication instruction,
i64 muls are turned into library calls to the _muldi3 function of libgcc, which
is supposed to perform 64-bit multiplications in software by using several
32-bit multiplications. However, as libgcc is compiled with -O2 by default
(which includes instcombine) the 32-bit multiplications in _muldi3 are promoted
to 64-bit multiplications, which is clearly not useful in this case :)
--
Configure bugmail: http://llvm.org/bugs/userprefs.cgi?tab=email
------- You are receiving this mail because: -------
You are on the CC list for the bug.
More information about the llvm-bugs
mailing list