1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-23 11:13:28 +01:00

Check for both styles of clobbers, those produced by dragonegg and

those produced by clang for the inline asm bswap conversion.

Modified from a patch by Chris Smowton.

llvm-svn: 194016
This commit is contained in:
Eric Christopher 2013-11-04 21:41:21 +00:00
parent 9eaaead296
commit a42eaab3a9
2 changed files with 41 additions and 20 deletions

View File

@ -19182,6 +19182,22 @@ namespace {
const VariadicFunction1<bool, StringRef, StringRef, matchAsmImpl> matchAsm={}; const VariadicFunction1<bool, StringRef, StringRef, matchAsmImpl> matchAsm={};
} }
static bool clobbersFlagRegisters(const SmallVector<StringRef, 4> &AsmPieces) {
if (AsmPieces.size() == 3 || AsmPieces.size() == 4) {
if (std::count(AsmPieces.begin(), AsmPieces.end(), "~{cc}") &&
std::count(AsmPieces.begin(), AsmPieces.end(), "~{flags}") &&
std::count(AsmPieces.begin(), AsmPieces.end(), "~{fpsr}")) {
if (AsmPieces.size() == 3)
return true;
else if (std::count(AsmPieces.begin(), AsmPieces.end(), "~{dirflag}"))
return true;
}
}
return false;
}
bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const { bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue()); InlineAsm *IA = cast<InlineAsm>(CI->getCalledValue());
@ -19223,12 +19239,8 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
const std::string &ConstraintsStr = IA->getConstraintString(); const std::string &ConstraintsStr = IA->getConstraintString();
SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ","); SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ",");
array_pod_sort(AsmPieces.begin(), AsmPieces.end()); array_pod_sort(AsmPieces.begin(), AsmPieces.end());
if (AsmPieces.size() == 4 && if (clobbersFlagRegisters(AsmPieces))
AsmPieces[0] == "~{cc}" && return IntrinsicLowering::LowerToByteSwap(CI);
AsmPieces[1] == "~{dirflag}" &&
AsmPieces[2] == "~{flags}" &&
AsmPieces[3] == "~{fpsr}")
return IntrinsicLowering::LowerToByteSwap(CI);
} }
break; break;
case 3: case 3:
@ -19241,11 +19253,7 @@ bool X86TargetLowering::ExpandInlineAsm(CallInst *CI) const {
const std::string &ConstraintsStr = IA->getConstraintString(); const std::string &ConstraintsStr = IA->getConstraintString();
SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ","); SplitString(StringRef(ConstraintsStr).substr(5), AsmPieces, ",");
array_pod_sort(AsmPieces.begin(), AsmPieces.end()); array_pod_sort(AsmPieces.begin(), AsmPieces.end());
if (AsmPieces.size() == 4 && if (clobbersFlagRegisters(AsmPieces))
AsmPieces[0] == "~{cc}" &&
AsmPieces[1] == "~{dirflag}" &&
AsmPieces[2] == "~{flags}" &&
AsmPieces[3] == "~{fpsr}")
return IntrinsicLowering::LowerToByteSwap(CI); return IntrinsicLowering::LowerToByteSwap(CI);
} }

View File

@ -2,18 +2,31 @@
; PR3701 ; PR3701
define i64 @t(i64* %arg) nounwind { define i64 @t(i64* %arg) nounwind {
br i1 true, label %1, label %5 br i1 true, label %1, label %5
; <label>:1 ; preds = %0 ; <label>:1 ; preds = %0
%2 = icmp eq i64* null, %arg ; <i1> [#uses=1] %2 = icmp eq i64* null, %arg ; <i1> [#uses=1]
%3 = tail call i64* asm sideeffect "movl %fs:0,$0", "=r,~{dirflag},~{fpsr},~{flags}"() nounwind ; <%struct.thread*> [#uses=0] %3 = tail call i64* asm sideeffect "movl %fs:0,$0", "=r,~{dirflag},~{fpsr},~{flags}"() nounwind ; <%struct.thread*> [#uses=0]
; CHECK: test ; CHECK: test
; CHECK-NEXT: j ; CHECK-NEXT: j
br i1 %2, label %4, label %5 br i1 %2, label %4, label %5
; <label>:4 ; preds = %1 ; <label>:4 ; preds = %1
ret i64 1 ret i64 1
; <label>:5 ; preds = %1 ; <label>:5 ; preds = %1
ret i64 0 ret i64 0
} }
; Make sure that we translate this to the bswap intrinsic which lowers down without the
; inline assembly.
; CHECK-NOT: #APP
define i32 @s(i32 %argc, i8** nocapture %argv) unnamed_addr nounwind {
entry:
%0 = trunc i32 %argc to i16
%asmtmp = tail call i16 asm "rorw $$8, ${0:w}", "=r,0,~{fpsr},~{flags},~{cc}"(i16 %0) nounwind, !srcloc !0
%1 = zext i16 %asmtmp to i32
ret i32 %1
}
!0 = metadata !{i64 935930}