]> granicus.if.org Git - clang/commitdiff
[CodeGen] Emit Constants for immediate inlineasm arguments.
authorAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 11 Jun 2015 18:19:34 +0000 (18:19 +0000)
committerAhmed Bougacha <ahmed.bougacha@gmail.com>
Thu, 11 Jun 2015 18:19:34 +0000 (18:19 +0000)
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

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@239549 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGStmt.cpp
test/CodeGen/inline-asm-immediate-ubsan.c [new file with mode: 0644]

index c879750015bf2ceb1c778671451b386c3831fd1b..744c61384c84bd4a129eb8744e7e1cac0acc23d5 100644 (file)
@@ -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/test/CodeGen/inline-asm-immediate-ubsan.c b/test/CodeGen/inline-asm-immediate-ubsan.c
new file mode 100644 (file)
index 0000000..2773c6e
--- /dev/null
@@ -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));
+}