summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAhmed Bougacha <ahmed.bougacha@gmail.com>2015-06-11 18:19:34 +0000
committerAhmed Bougacha <ahmed.bougacha@gmail.com>2015-06-11 18:19:34 +0000
commitff75f3dd6c3bd7a51839765d2f1f4e427888dfa4 (patch)
treeffb97de86cfa349652d63ea2788965a818176de0
parent89e39a7d6f6d7bc67db423d8b82124136d0076b0 (diff)
downloadbcm5719-llvm-ff75f3dd6c3bd7a51839765d2f1f4e427888dfa4.tar.gz
bcm5719-llvm-ff75f3dd6c3bd7a51839765d2f1f4e427888dfa4.zip
[CodeGen] Emit Constants for immediate inlineasm arguments.
For inline assembly immediate constraints, we currently always use EmitScalarExpr, instead of directly emitting the constant. When the overflow sanitizer is enabled, this generates overflow intrinsics instead of constants. Instead, emit a constant for constraints that either require an immediate (e.g. 'I' on X86), or only accepts constants (immediate or symbolic; i.e., don't accept registers or memory). Fixes PR19763. Differential Revision: http://reviews.llvm.org/D10255 llvm-svn: 239549
-rw-r--r--clang/lib/CodeGen/CGStmt.cpp10
-rw-r--r--clang/test/CodeGen/inline-asm-immediate-ubsan.c25
2 files changed, 35 insertions, 0 deletions
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index c879750015b..744c61384c8 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -1750,6 +1750,16 @@ llvm::Value* CodeGenFunction::EmitAsmInput(
const TargetInfo::ConstraintInfo &Info,
const Expr *InputExpr,
std::string &ConstraintStr) {
+ // If this can't be a register or memory, i.e., has to be a constant
+ // (immediate or symbolic), try to emit it as such.
+ if (!Info.allowsRegister() && !Info.allowsMemory()) {
+ llvm::APSInt Result;
+ if (InputExpr->isIntegerConstantExpr(Result, getContext()))
+ return llvm::ConstantInt::get(getLLVMContext(), Result);
+ assert(!Info.requiresImmediateConstant() &&
+ "Required-immediate inlineasm arg isn't constant?");
+ }
+
if (Info.allowsRegister() || !Info.allowsMemory())
if (CodeGenFunction::hasScalarEvaluationKind(InputExpr->getType()))
return EmitScalarExpr(InputExpr);
diff --git a/clang/test/CodeGen/inline-asm-immediate-ubsan.c b/clang/test/CodeGen/inline-asm-immediate-ubsan.c
new file mode 100644
index 00000000000..2773c6eb9d7
--- /dev/null
+++ b/clang/test/CodeGen/inline-asm-immediate-ubsan.c
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -emit-llvm -o - %s \
+// RUN: -fsanitize=signed-integer-overflow \
+// RUN: | FileCheck %s --check-prefix=CHECK
+
+// Verify we emit constants for "immediate" inline assembly arguments.
+// Emitting a scalar expression can make the immediate be generated as
+// overflow intrinsics, if the overflow sanitizer is enabled.
+
+// Check both 'i' and 'I':
+// - 'i' accepts symbolic constants.
+// - 'I' doesn't, and is really an immediate-required constraint.
+
+// See also PR23517.
+
+// CHECK-LABEL: @test_inlineasm_i
+// CHECK: call void asm sideeffect "int $0", "i{{.*}}"(i32 2)
+void test_inlineasm_i() {
+ __asm__ __volatile__("int %0" :: "i"(1 + 1));
+}
+
+// CHECK-LABEL: @test_inlineasm_I
+// CHECK: call void asm sideeffect "int $0", "I{{.*}}"(i32 2)
+void test_inlineasm_I() {
+ __asm__ __volatile__("int %0" :: "I"(1 + 1));
+}
OpenPOWER on IntegriCloud