#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"
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;
}
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
}
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: