summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEric Christopher <echristo@gmail.com>2013-01-31 00:50:46 +0000
committerEric Christopher <echristo@gmail.com>2013-01-31 00:50:46 +0000
commit4e3e94c13d0f427c11f32b25d436bcb88e26367d (patch)
tree60df1f928e32b20f2ab26f22f1e64f99a55396e0
parent7e6f928a7adc25d769eb1986629630c36f4cc094 (diff)
downloadbcm5719-llvm-4e3e94c13d0f427c11f32b25d436bcb88e26367d.tar.gz
bcm5719-llvm-4e3e94c13d0f427c11f32b25d436bcb88e26367d.zip
Check and allow floating point registers to select the size of the
register for inline asm. This conforms to how gcc allows for effective casting of inputs into gprs (fprs is already handled). llvm-svn: 174008
-rw-r--r--llvm/lib/Target/X86/X86ISelLowering.cpp4
-rw-r--r--llvm/test/CodeGen/X86/cas.ll42
2 files changed, 44 insertions, 2 deletions
diff --git a/llvm/lib/Target/X86/X86ISelLowering.cpp b/llvm/lib/Target/X86/X86ISelLowering.cpp
index 36d1ad42677..c34010c9787 100644
--- a/llvm/lib/Target/X86/X86ISelLowering.cpp
+++ b/llvm/lib/Target/X86/X86ISelLowering.cpp
@@ -18170,7 +18170,7 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Res.first = DestReg;
Res.second = &X86::GR8RegClass;
}
- } else if (VT == MVT::i32) {
+ } else if (VT == MVT::i32 || VT == MVT::f32) {
unsigned DestReg = 0;
switch (Res.first) {
default: break;
@@ -18187,7 +18187,7 @@ X86TargetLowering::getRegForInlineAsmConstraint(const std::string &Constraint,
Res.first = DestReg;
Res.second = &X86::GR32RegClass;
}
- } else if (VT == MVT::i64) {
+ } else if (VT == MVT::i64 || VT == MVT::f64) {
unsigned DestReg = 0;
switch (Res.first) {
default: break;
diff --git a/llvm/test/CodeGen/X86/cas.ll b/llvm/test/CodeGen/X86/cas.ll
new file mode 100644
index 00000000000..12e49f94704
--- /dev/null
+++ b/llvm/test/CodeGen/X86/cas.ll
@@ -0,0 +1,42 @@
+; RUN: llc -mtriple=x86_64-pc-linux-gnu %s -o - | FileCheck %s
+
+; C code this came from
+;bool cas(float volatile *p, float *expected, float desired) {
+; bool success;
+; __asm__ __volatile__("lock; cmpxchg %[desired], %[mem]; "
+; "mov %[expected], %[expected_out]; "
+; "sete %[success]"
+; : [success] "=a" (success),
+; [expected_out] "=rm" (*expected)
+; : [expected] "a" (*expected),
+; [desired] "q" (desired),
+; [mem] "m" (*p)
+; : "memory", "cc");
+; return success;
+;}
+
+define zeroext i1 @cas(float* %p, float* %expected, float %desired) nounwind {
+entry:
+ %p.addr = alloca float*, align 8
+ %expected.addr = alloca float*, align 8
+ %desired.addr = alloca float, align 4
+ %success = alloca i8, align 1
+ store float* %p, float** %p.addr, align 8
+ store float* %expected, float** %expected.addr, align 8
+ store float %desired, float* %desired.addr, align 4
+ %0 = load float** %expected.addr, align 8
+ %1 = load float** %expected.addr, align 8
+ %2 = load float* %1, align 4
+ %3 = load float* %desired.addr, align 4
+ %4 = load float** %p.addr, align 8
+ %5 = call i8 asm sideeffect "lock; cmpxchg $3, $4; mov $2, $1; sete $0", "={ax},=*rm,{ax},q,*m,~{memory},~{cc},~{dirflag},~{fpsr},~{flags}"(float* %0, float %2, float %3, float* %4) nounwind
+ store i8 %5, i8* %success, align 1
+ %6 = load i8* %success, align 1
+ %tobool = trunc i8 %6 to i1
+ ret i1 %tobool
+}
+
+; Make sure we're emitting a move from
+; CHECK: #APP
+; CHECK-NEXT: lock;{{.*}}mov %eax,{{.*}}
+; CHECK-NEXT: #NO_APP
OpenPOWER on IntegriCloud