Quuxplusone / LLVMBugzillaTest

0 stars 0 forks source link

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

Open Quuxplusone opened 11 years ago

Quuxplusone commented 11 years ago
Bugzilla Link PR15010
Status NEW
Importance P normal
Reported by Michael Gottesman (mgottesman@apple.com)
Reported on 2013-01-20 15:22:32 -0800
Last modified on 2018-10-25 20:12:08 -0700
Version trunk
Hardware PC All
CC llvm-bugs@lists.llvm.org, pawel@32bitmicro.com, richard-llvm@metafoo.co.uk
Fixed by commit(s)
Attachments
Blocks
Blocked by
See also
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
}
-----
Quuxplusone 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
}
-----