Skip to content

Commit

Permalink
[Clang] Fix crash for incompatible types in inline assembly (llvm#119098
Browse files Browse the repository at this point in the history
)

Fixed issue llvm#118892.
  • Loading branch information
AdUhTkJm authored Dec 17, 2024
1 parent 24c2744 commit 449af81
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 1 deletion.
7 changes: 6 additions & 1 deletion clang/lib/Sema/SemaStmtAsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -664,11 +664,16 @@ StmtResult Sema::ActOnGCCAsmStmt(SourceLocation AsmLoc, bool IsSimple,
SmallerValueMentioned |= OutSize < InSize;
}

// If the input is an integer register while the output is floating point,
// or vice-versa, there is no way they can work together.
bool FPTiedToInt = (InputDomain == AD_FP) ^ (OutputDomain == AD_FP);

// If the smaller value wasn't mentioned in the asm string, and if the
// output was a register, just extend the shorter one to the size of the
// larger one.
if (!SmallerValueMentioned && InputDomain != AD_Other &&
if (!SmallerValueMentioned && !FPTiedToInt && InputDomain != AD_Other &&
OutputConstraintInfos[TiedTo].allowsRegister()) {

// FIXME: GCC supports the OutSize to be 128 at maximum. Currently codegen
// crash when the size larger than the register size. So we limit it here.
if (OutTy->isStructureType() &&
Expand Down
21 changes: 21 additions & 0 deletions clang/test/Sema/asm.c
Original file line number Diff line number Diff line change
Expand Up @@ -365,3 +365,24 @@ void test19(long long x)
// FIXME: This case should be supported by codegen, but it fails now.
asm ("" : "=rm" (x): "0" (e)); // expected-error {{unsupported inline asm: input with type 'st_size128' (aka 'struct _st_size128') matching output with type 'long long'}}
}

typedef int int2 __attribute__((ext_vector_type(2)));

// GH118892
void test20(char x) {
double d;
float f;

asm ("fabs" : "=t" (d): "0" (x)); // expected-error {{unsupported inline asm: input with type 'char' matching output with type 'double'}}
asm ("fabs" : "=t" (x): "0" (d)); // expected-error {{unsupported inline asm: input with type 'double' matching output with type 'char'}}
asm ("fabs" : "=t" (f): "0" (d)); // no-error
asm ("fabs" : "=t" (d): "0" (f)); // no-error

st_size64 a;
asm ("fabs" : "=t" (d): "0" (a)); // expected-error {{unsupported inline asm: input with type 'st_size64' (aka 'struct _st_size64') matching output with type 'double'}}
asm ("fabs" : "=t" (a): "0" (d)); // expected-error {{unsupported inline asm: input with type 'double' matching output with type 'st_size64' (aka 'struct _st_size64')}}

int2 v;
asm ("fabs" : "=t" (d): "0" (v)); // expected-error {{unsupported inline asm: input with type 'int2' (vector of 2 'int' values) matching output with type 'double'}}
asm ("fabs" : "=t" (v): "0" (d)); // expected-error {{unsupported inline asm: input with type 'double' matching output with type 'int2' (vector of 2 'int' values)}}
}

0 comments on commit 449af81

Please sign in to comment.