Skip to content

Commit 0a3516b

Browse files
committed
[CodeGen] Allow mixed scalar type constraints for inline asm
GCC supports code like "asm volatile ("" : "=r" (i) : "0" (f))" where i is integer type and f is floating point type. Currently this code produces an error with Clang. The change allows mixed scalar types between input and output constraints.
1 parent ddfc7e2 commit 0a3516b

File tree

3 files changed

+82
-4
lines changed

3 files changed

+82
-4
lines changed

llvm/lib/CodeGen/SelectionDAG/SelectionDAGBuilder.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9041,8 +9041,11 @@ static void patchMatchingInput(const SDISelAsmOperandInfo &OpInfo,
90419041
std::pair<unsigned, const TargetRegisterClass *> InputRC =
90429042
TLI.getRegForInlineAsmConstraint(TRI, MatchingOpInfo.ConstraintCode,
90439043
MatchingOpInfo.ConstraintVT);
9044-
if ((OpInfo.ConstraintVT.isInteger() !=
9045-
MatchingOpInfo.ConstraintVT.isInteger()) ||
9044+
const bool OutOpIsIntOrFP =
9045+
OpInfo.ConstraintVT.isInteger() || OpInfo.ConstraintVT.isFloatingPoint();
9046+
const bool InOpInfoIsIntOrFP = MatchingOpInfo.ConstraintVT.isInteger() ||
9047+
MatchingOpInfo.ConstraintVT.isFloatingPoint();
9048+
if ((OutOpIsIntOrFP != InOpInfoIsIntOrFP) ||
90469049
(MatchRC.second != InputRC.second)) {
90479050
// FIXME: error out in a more elegant fashion
90489051
report_fatal_error("Unsupported asm: input constraint"

llvm/lib/CodeGen/SelectionDAG/TargetLowering.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5772,8 +5772,11 @@ TargetLowering::ParseConstraints(const DataLayout &DL,
57725772
std::pair<unsigned, const TargetRegisterClass *> InputRC =
57735773
getRegForInlineAsmConstraint(TRI, Input.ConstraintCode,
57745774
Input.ConstraintVT);
5775-
if ((OpInfo.ConstraintVT.isInteger() !=
5776-
Input.ConstraintVT.isInteger()) ||
5775+
const bool OutOpIsIntOrFP = OpInfo.ConstraintVT.isInteger() ||
5776+
OpInfo.ConstraintVT.isFloatingPoint();
5777+
const bool InOpIsIntOrFP = Input.ConstraintVT.isInteger() ||
5778+
Input.ConstraintVT.isFloatingPoint();
5779+
if ((OutOpIsIntOrFP != InOpIsIntOrFP) ||
57775780
(MatchRC.second != InputRC.second)) {
57785781
report_fatal_error("Unsupported asm: input constraint"
57795782
" with a matching output constraint of"
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py UTC_ARGS: --version 4
2+
; RUN: llc -mtriple=x86_64-unknown-linux-gnu < %s | FileCheck %s
3+
4+
; C source used for generating this test:
5+
6+
; unsigned test(float f)
7+
; {
8+
; unsigned i;
9+
; asm volatile ("" : "=r" (i) : "0" (f));
10+
; return i;
11+
; }
12+
13+
14+
define i32 @test_int_float(float %f) {
15+
; CHECK-LABEL: test_int_float:
16+
; CHECK: # %bb.0: # %entry
17+
; CHECK-NEXT: movss %xmm0, -{{[0-9]+}}(%rsp)
18+
; CHECK-NEXT: movl -{{[0-9]+}}(%rsp), %eax
19+
; CHECK-NEXT: #APP
20+
; CHECK-NEXT: #NO_APP
21+
; CHECK-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
22+
; CHECK-NEXT: retq
23+
entry:
24+
%f.addr = alloca float, align 4
25+
%i = alloca i32, align 4
26+
store float %f, ptr %f.addr, align 4
27+
%load_f = load float, ptr %f.addr, align 4
28+
%asm_call = call i32 asm sideeffect "", "=r,0,~{dirflag},~{fpsr},~{flags}"(float %load_f)
29+
store i32 %asm_call, ptr %i, align 4
30+
%load_i = load i32, ptr %i, align 4
31+
ret i32 %load_i
32+
}
33+
34+
define i32 @test_int_ptr(float* %f) {
35+
; CHECK-LABEL: test_int_ptr:
36+
; CHECK: # %bb.0: # %entry
37+
; CHECK-NEXT: movq %rdi, %rax
38+
; CHECK-NEXT: movq %rdi, -{{[0-9]+}}(%rsp)
39+
; CHECK-NEXT: #APP
40+
; CHECK-NEXT: #NO_APP
41+
; CHECK-NEXT: movl %eax, -{{[0-9]+}}(%rsp)
42+
; CHECK-NEXT: # kill: def $eax killed $eax killed $rax
43+
; CHECK-NEXT: retq
44+
entry:
45+
%f.addr = alloca float*, align 4
46+
%i = alloca i32, align 4
47+
store float* %f, ptr %f.addr, align 4
48+
%load_f = load float*, ptr %f.addr, align 4
49+
%asm_call = call i32 asm sideeffect "", "=r,0,~{dirflag},~{fpsr},~{flags}"(float* %load_f)
50+
store i32 %asm_call, ptr %i, align 4
51+
%load_i = load i32, ptr %i, align 4
52+
ret i32 %load_i
53+
}
54+
55+
define <4 x i32> @test_int_vec(<4 x float> %f) {
56+
; CHECK-LABEL: test_int_vec:
57+
; CHECK: # %bb.0: # %entry
58+
; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp)
59+
; CHECK-NEXT: #APP
60+
; CHECK-NEXT: #NO_APP
61+
; CHECK-NEXT: movaps %xmm0, -{{[0-9]+}}(%rsp)
62+
; CHECK-NEXT: retq
63+
entry:
64+
%f.addr = alloca <4 x float>, align 16
65+
%i = alloca <4 x i32>, align 16
66+
store <4 x float> %f, <4 x float>* %f.addr, align 16
67+
%load_f = load <4 x float>, <4 x float>* %f.addr, align 16
68+
%asm_call = call <4 x i32> asm sideeffect "", "=v,0,~{dirflag},~{fpsr},~{flags}"(<4 x float> %load_f)
69+
store <4 x i32> %asm_call, <4 x i32>* %i, align 16
70+
%load_i = load <4 x i32>, <4 x i32>* %i, align 16
71+
ret <4 x i32> %load_i
72+
}

0 commit comments

Comments
 (0)