llvm / llvm-project

The LLVM Project is a collection of modular and reusable compiler and toolchain technologies.
http://llvm.org
Other
29.04k stars 11.98k forks source link

Clang coerces {int,unsigned} __attribute__((ext_vector_type(2))) to doubles. #15382

Open gottesmm opened 11 years ago

gottesmm commented 11 years ago
Bugzilla Link 15010
Version trunk
OS All
CC @zygoloid

Extended Description

Clang compiles the following c file:


typedef int int2 attribute((ext_vector_type(2))); typedef unsigned uint2 attribute((ext_vector_type(2)));

int2 test(int2 x, int2 y) { return x + y; }

uint2 test2(uint2 x, uint2 y) { return x + y; }

to the following IR using 'clang -c test.c -emit-llvm -S -o -':


; ModuleID = 'test.c' 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-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.8.0"

define double @​test(double %x.coerce, double %y.coerce) nounwind uwtable ssp { entry: %retval = alloca <2 x i32>, align 8 %x = alloca <2 x i32>, align 8 %x.addr = alloca <2 x i32>, align 8 %y = alloca <2 x i32>, align 8 %y.addr = alloca <2 x i32>, align 8 %0 = bitcast <2 x i32> %x to double store double %x.coerce, double %0, align 1 %x1 = load <2 x i32> %x, align 8 store <2 x i32> %x1, <2 x i32> %x.addr, align 8 %1 = bitcast <2 x i32> %y to double store double %y.coerce, double %1, align 1 %y2 = load <2 x i32> %y, align 8 store <2 x i32> %y2, <2 x i32> %y.addr, align 8 %2 = load <2 x i32> %x.addr, align 8 %3 = load <2 x i32> %y.addr, align 8 %add = add <2 x i32> %2, %3 store <2 x i32> %add, <2 x i32> %retval %4 = bitcast <2 x i32> %retval to double %5 = load double %4, align 1 ret double %5 }

define double @​test2(double %x.coerce, double %y.coerce) nounwind uwtable ssp { entry: %retval = alloca <2 x i32>, align 8 %x = alloca <2 x i32>, align 8 %x.addr = alloca <2 x i32>, align 8 %y = alloca <2 x i32>, align 8 %y.addr = alloca <2 x i32>, align 8 %0 = bitcast <2 x i32> %x to double store double %x.coerce, double %0, align 1 %x1 = load <2 x i32> %x, align 8 store <2 x i32> %x1, <2 x i32> %x.addr, align 8 %1 = bitcast <2 x i32> %y to double store double %y.coerce, double %1, align 1 %y2 = load <2 x i32> %y, align 8 store <2 x i32> %y2, <2 x i32> %y.addr, align 8 %2 = load <2 x i32> %x.addr, align 8 %3 = load <2 x i32> %y.addr, align 8 %add = add <2 x i32> %2, %3 store <2 x i32> %add, <2 x i32> %retval %4 = bitcast <2 x i32> %retval to double %5 = load double %4, align 1 ret double %5 }

gottesmm commented 2 years ago

mentioned in issue llvm/llvm-bugzilla-archive#15011

gottesmm commented 11 years ago

The same seems to happen with float2:


typedef float float2 attribute((ext_vector_type(2)));

float2 test3(float2 x, float2 y) { return x + y; }


define double @​test3(double %x.coerce, double %y.coerce) nounwind uwtable ssp { entry: %retval = alloca <2 x float>, align 8 %x = alloca <2 x float>, align 8 %x.addr = alloca <2 x float>, align 8 %y = alloca <2 x float>, align 8 %y.addr = alloca <2 x float>, align 8 %0 = bitcast <2 x float> %x to double store double %x.coerce, double %0, align 1 %x1 = load <2 x float> %x, align 8 store <2 x float> %x1, <2 x float> %x.addr, align 8 %1 = bitcast <2 x float> %y to double store double %y.coerce, double %1, align 1 %y2 = load <2 x float> %y, align 8 store <2 x float> %y2, <2 x float> %y.addr, align 8 %2 = load <2 x float> %x.addr, align 8 %3 = load <2 x float> %y.addr, align 8 %add = fadd <2 x float> %2, %3 store <2 x float> %add, <2 x float> %retval %4 = bitcast <2 x float> %retval to double %5 = load double %4, align 1 ret double %5 }