Hi dsanders, ahatanak, t.p.northover,

Same problem as D10045 / [[ https://llvm.org/bugs/show_bug.cgi?id=23517 | 
PR23517 ]], slightly different solution.

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, I think).

(re-send on cfe-commits of D10254)

http://reviews.llvm.org/D10255

Files:
  lib/CodeGen/CGStmt.cpp
  test/CodeGen/inline-asm-immediate-ubsan.c

Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -1750,6 +1750,16 @@
                                          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);
Index: test/CodeGen/inline-asm-immediate-ubsan.c
===================================================================
--- test/CodeGen/inline-asm-immediate-ubsan.c
+++ 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));
+}

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
Index: lib/CodeGen/CGStmt.cpp
===================================================================
--- lib/CodeGen/CGStmt.cpp
+++ lib/CodeGen/CGStmt.cpp
@@ -1750,6 +1750,16 @@
                                          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);
Index: test/CodeGen/inline-asm-immediate-ubsan.c
===================================================================
--- test/CodeGen/inline-asm-immediate-ubsan.c
+++ 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));
+}
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits

Reply via email to