[cfe-commits] r108489 - in /cfe/trunk: lib/CodeGen/CGStmt.cpp lib/CodeGen/CodeGenFunction.h test/CodeGen/asm-inout.c
Eli Friedman
eli.friedman at gmail.com
Thu Jul 15 17:55:21 PDT 2010
Author: efriedma
Date: Thu Jul 15 19:55:21 2010
New Revision: 108489
URL: http://llvm.org/viewvc/llvm-project?rev=108489&view=rev
Log:
Fix for PR3800: make sure not to evaluate the expression for a read-write
asm operand twice.
Added:
cfe/trunk/test/CodeGen/asm-inout.c
Modified:
cfe/trunk/lib/CodeGen/CGStmt.cpp
cfe/trunk/lib/CodeGen/CodeGenFunction.h
Modified: cfe/trunk/lib/CodeGen/CGStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGStmt.cpp?rev=108489&r1=108488&r2=108489&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGStmt.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGStmt.cpp Thu Jul 15 19:55:21 2010
@@ -888,40 +888,50 @@
return Result;
}
-llvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S,
- const TargetInfo::ConstraintInfo &Info,
- const Expr *InputExpr,
- std::string &ConstraintStr) {
+llvm::Value*
+CodeGenFunction::EmitAsmInputLValue(const AsmStmt &S,
+ const TargetInfo::ConstraintInfo &Info,
+ LValue InputValue, QualType InputType,
+ std::string &ConstraintStr) {
llvm::Value *Arg;
if (Info.allowsRegister() || !Info.allowsMemory()) {
- if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType())) {
- Arg = EmitScalarExpr(InputExpr);
+ if (!CodeGenFunction::hasAggregateLLVMType(InputType)) {
+ Arg = EmitLoadOfLValue(InputValue, InputType).getScalarVal();
} else {
- InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
- LValue Dest = EmitLValue(InputExpr);
-
- const llvm::Type *Ty = ConvertType(InputExpr->getType());
+ const llvm::Type *Ty = ConvertType(InputType);
uint64_t Size = CGM.getTargetData().getTypeSizeInBits(Ty);
if (Size <= 64 && llvm::isPowerOf2_64(Size)) {
Ty = llvm::IntegerType::get(VMContext, Size);
Ty = llvm::PointerType::getUnqual(Ty);
- Arg = Builder.CreateLoad(Builder.CreateBitCast(Dest.getAddress(), Ty));
+ Arg = Builder.CreateLoad(Builder.CreateBitCast(InputValue.getAddress(),
+ Ty));
} else {
- Arg = Dest.getAddress();
+ Arg = InputValue.getAddress();
ConstraintStr += '*';
}
}
} else {
- InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
- LValue Dest = EmitLValue(InputExpr);
- Arg = Dest.getAddress();
+ Arg = InputValue.getAddress();
ConstraintStr += '*';
}
return Arg;
}
+llvm::Value* CodeGenFunction::EmitAsmInput(const AsmStmt &S,
+ const TargetInfo::ConstraintInfo &Info,
+ const Expr *InputExpr,
+ std::string &ConstraintStr) {
+ if (Info.allowsRegister() || !Info.allowsMemory())
+ if (!CodeGenFunction::hasAggregateLLVMType(InputExpr->getType()))
+ return EmitScalarExpr(InputExpr);
+
+ InputExpr = InputExpr->IgnoreParenNoopCasts(getContext());
+ LValue Dest = EmitLValue(InputExpr);
+ return EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(), ConstraintStr);
+}
+
void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
// Analyze the asm string to decompose it into its pieces. We know that Sema
// has already done this, so it is guaranteed to be successful.
@@ -1031,7 +1041,8 @@
InOutConstraints += ',';
const Expr *InputExpr = S.getOutputExpr(i);
- llvm::Value *Arg = EmitAsmInput(S, Info, InputExpr, InOutConstraints);
+ llvm::Value *Arg = EmitAsmInputLValue(S, Info, Dest, InputExpr->getType(),
+ InOutConstraints);
if (Info.allowsRegister())
InOutConstraints += llvm::utostr(i);
Modified: cfe/trunk/lib/CodeGen/CodeGenFunction.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenFunction.h?rev=108489&r1=108488&r2=108489&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenFunction.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenFunction.h Thu Jul 15 19:55:21 2010
@@ -1575,6 +1575,11 @@
const TargetInfo::ConstraintInfo &Info,
const Expr *InputExpr, std::string &ConstraintStr);
+ llvm::Value* EmitAsmInputLValue(const AsmStmt &S,
+ const TargetInfo::ConstraintInfo &Info,
+ LValue InputValue, QualType InputType,
+ std::string &ConstraintStr);
+
/// EmitCallArgs - Emit call arguments for a function.
/// The CallArgTypeInfo parameter is used for iterating over the known
/// argument types of the function being called.
Added: cfe/trunk/test/CodeGen/asm-inout.c
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGen/asm-inout.c?rev=108489&view=auto
==============================================================================
--- cfe/trunk/test/CodeGen/asm-inout.c (added)
+++ cfe/trunk/test/CodeGen/asm-inout.c Thu Jul 15 19:55:21 2010
@@ -0,0 +1,19 @@
+// RUN: %clang_cc1 -triple i386-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+// PR3800
+int *foo(void);
+
+// CHECK: @test1
+void test1() {
+ // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo()
+ // CHECK: call void asm "foobar", "=*m,*m,~{dirflag},~{fpsr},~{flags}"(i32* [[REGCALLRESULT]], i32* [[REGCALLRESULT]])
+ asm ("foobar" : "+m"(*foo()));
+}
+
+// CHECK: @test2
+void test2() {
+ // CHECK: [[REGCALLRESULT:%[a-zA-Z0-9\.]+]] = call i32* @foo()
+ // CHECK: load i32* [[REGCALLRESULT]]
+ // CHECK: call i32 asm
+ // CHECK: store i32 {{%[a-zA-Z0-9\.]+}}, i32* [[REGCALLRESULT]]
+ asm ("foobar" : "+r"(*foo()));
+}
More information about the cfe-commits
mailing list