[Attributor] Make non-side-effect inline asm be "no-call"
authorJohannes Doerfert <johannes@jdoerfert.de>
Tue, 4 Oct 2022 14:39:45 +0000 (07:39 -0700)
committerJohannes Doerfert <johannes@jdoerfert.de>
Tue, 13 Dec 2022 04:55:35 +0000 (20:55 -0800)
If we have inline asm with side effects we assume any function might be
called. For non-side-effect asm we now assume no function is called.

llvm/lib/Transforms/IPO/AttributorAttributes.cpp
llvm/test/Transforms/Attributor/nosync.ll
llvm/test/Transforms/Attributor/reachability.ll

index b5ca98d..0c16fbd 100644 (file)
@@ -44,6 +44,7 @@
 #include "llvm/IR/DerivedTypes.h"
 #include "llvm/IR/GlobalValue.h"
 #include "llvm/IR/IRBuilder.h"
+#include "llvm/IR/InlineAsm.h"
 #include "llvm/IR/InstrTypes.h"
 #include "llvm/IR/Instruction.h"
 #include "llvm/IR/Instructions.h"
@@ -9665,10 +9666,12 @@ struct AACallEdgesCallSite : public AACallEdgesImpl {
 
     CallBase *CB = cast<CallBase>(getCtxI());
 
-    if (CB->isInlineAsm()) {
-      if (!hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
-          !hasAssumption(*CB, "ompx_no_call_asm"))
+    if (auto *IA = dyn_cast<InlineAsm>(CB->getCalledOperand())) {
+      if (IA->hasSideEffects() &&
+          !hasAssumption(*CB->getCaller(), "ompx_no_call_asm") &&
+          !hasAssumption(*CB, "ompx_no_call_asm")) {
         setHasUnknownCallee(false, Change);
+      }
       return Change;
     }
 
index 324c49f..1133cdf 100644 (file)
@@ -379,10 +379,10 @@ define i32 @memset_non_volatile(i8* %ptr1, i8 %val) {
 define i32 @inline_asm_test(i32 %x) {
 ; CHECK-LABEL: define {{[^@]+}}@inline_asm_test
 ; CHECK-SAME: (i32 [[X:%.*]]) {
-; CHECK-NEXT:    [[TMP1:%.*]] = call i32 asm "bswap $0", "=r,r"(i32 [[X]])
+; CHECK-NEXT:    [[TMP1:%.*]] = call i32 asm sideeffect "bswap $0", "=r,r"(i32 [[X]])
 ; CHECK-NEXT:    ret i32 4
 ;
-  call i32 asm "bswap $0", "=r,r"(i32 %x)
+  call i32 asm sideeffect "bswap $0", "=r,r"(i32 %x)
   ret i32 4
 }
 
index 76c448c..0852479 100644 (file)
@@ -28,6 +28,19 @@ entry:
   ret void
 }
 
+define void @non_recursive_asm_no_sideffect() {
+; CHECK: Function Attrs: norecurse
+; CHECK-LABEL: define {{[^@]+}}@non_recursive_asm_no_sideffect
+; CHECK-SAME: () #[[ATTR1]] {
+; CHECK-NEXT:  entry:
+; CHECK-NEXT:    call void asm "foobar
+; CHECK-NEXT:    ret void
+;
+entry:
+  call void asm "foobar;", ""()
+  ret void
+}
+
 define void @recursive_asm() {
 ; CHECK-LABEL: define {{[^@]+}}@recursive_asm() {
 ; CHECK-NEXT:  entry: