diff options
Diffstat (limited to 'test/Feature')
| -rw-r--r-- | test/Feature/OperandBundles/adce.ll | 49 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/basic-aa-argmemonly.ll | 51 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/dse.ll | 62 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/early-cse.ll | 89 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/function-attrs.ll | 33 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/inliner-conservative.ll | 17 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/merge-func.ll | 64 | ||||
| -rw-r--r-- | test/Feature/OperandBundles/special-state.ll | 21 | ||||
| -rw-r--r-- | test/Feature/alias2.ll | 24 | ||||
| -rw-r--r-- | test/Feature/aliases.ll | 18 | ||||
| -rw-r--r-- | test/Feature/callingconventions.ll | 7 | ||||
| -rw-r--r-- | test/Feature/comdat.ll | 4 | ||||
| -rw-r--r-- | test/Feature/exception.ll | 109 | ||||
| -rw-r--r-- | test/Feature/optnone-llc.ll | 10 |
14 files changed, 533 insertions, 25 deletions
diff --git a/test/Feature/OperandBundles/adce.ll b/test/Feature/OperandBundles/adce.ll new file mode 100644 index 000000000000..a729ba710689 --- /dev/null +++ b/test/Feature/OperandBundles/adce.ll @@ -0,0 +1,49 @@ +; RUN: opt -S -adce < %s | FileCheck %s + +; While it is normally okay to DCE out calls to @readonly_function and +; @readnone_function, we cannot do that if they're carrying operand +; bundles since the presence of unknown operand bundles implies +; arbitrary memory effects. + +declare void @readonly_function() readonly nounwind +declare void @readnone_function() readnone nounwind + +define void @test0() { +; CHECK-LABEL: @test0( + entry: + call void @readonly_function() [ "tag"() ] +; CHECK: call void @readonly_function + ret void +} + +define void @test1() { +; CHECK-LABEL: @test1( + entry: + call void @readnone_function() [ "tag"() ] +; CHECK: call void @readnone_function + ret void +} + +define void @test2() { +; CHECK-LABEL: @test2( + entry: +; CHECK-NOT: @readonly_function( + call void @readonly_function() readonly [ "tag"() ] + ret void +} + +define void @test3() { +; CHECK-LABEL: @test3( + entry: +; CHECK-NOT: @readnone_function( + call void @readnone_function() readnone [ "tag"() ] + ret void +} + +define void @test4() { +; CHECK-LABEL: @test4( + entry: +; CHECK-NOT: @readonly_function() + call void @readonly_function() [ "deopt"() ] + ret void +} diff --git a/test/Feature/OperandBundles/basic-aa-argmemonly.ll b/test/Feature/OperandBundles/basic-aa-argmemonly.ll new file mode 100644 index 000000000000..aa9445886060 --- /dev/null +++ b/test/Feature/OperandBundles/basic-aa-argmemonly.ll @@ -0,0 +1,51 @@ +; RUN: opt -S -basicaa -gvn < %s | FileCheck %s + +declare void @argmemonly_function(i32 *) argmemonly + +define i32 @test0(i32* %P, i32* noalias %P2) { +; CHECK-LABEL: @test0( + %v1 = load i32, i32* %P +; CHECK: %v1 = load i32, i32* %P + call void @argmemonly_function(i32* %P2) [ "tag"() ] +; CHECK: call void @argmemonly_function( + %v2 = load i32, i32* %P +; CHECK: %v2 = load i32, i32* %P + %diff = sub i32 %v1, %v2 +; CHECK: %diff = sub i32 %v1, %v2 + ret i32 %diff +; CHECK: ret i32 %diff +} + +define i32 @test1(i32* %P, i32* noalias %P2) { +; CHECK-LABEL: @test1( + %v1 = load i32, i32* %P + call void @argmemonly_function(i32* %P2) argmemonly [ "tag"() ] +; CHECK: call void @argmemonly_function( + %v2 = load i32, i32* %P + %diff = sub i32 %v1, %v2 + ret i32 %diff +; CHECK: ret i32 0 +} + +define i32 @test2(i32* %P, i32* noalias %P2) { +; Note: in this test we //can// GVN %v1 and %v2 into one value in theory. Calls +; with deopt operand bundles are not argmemonly because they *read* the entire +; heap, but they don't write to any location in the heap if the callee does not +; deoptimize the caller. This fact, combined with the fact that +; @argmemonly_function is, well, an argmemonly function, can be used to conclude +; that %P is not written to at the callsite. However LLVM currently cannot +; describe the "does not write to non-args, and reads the entire heap" effect on +; a callsite. + +; CHECK-LABEL: @test2( + %v1 = load i32, i32* %P +; CHECK: %v1 = load i32, i32* %P + call void @argmemonly_function(i32* %P2) [ "deopt"() ] +; CHECK: call void @argmemonly_function( + %v2 = load i32, i32* %P +; CHECK: %v2 = load i32, i32* %P + %diff = sub i32 %v1, %v2 +; CHECK: %diff = sub i32 %v1, %v2 + ret i32 %diff +; CHECK: ret i32 %diff +} diff --git a/test/Feature/OperandBundles/dse.ll b/test/Feature/OperandBundles/dse.ll new file mode 100644 index 000000000000..9ddf7f02e384 --- /dev/null +++ b/test/Feature/OperandBundles/dse.ll @@ -0,0 +1,62 @@ +; RUN: opt -S -dse < %s | FileCheck %s + +declare void @f() +declare noalias i8* @malloc(i32) nounwind + +define void @test_0() { +; CHECK-LABEL: @test_0( + %m = call i8* @malloc(i32 24) + tail call void @f() [ "unknown"(i8* %m) ] +; CHECK: store i8 -19, i8* %m + store i8 -19, i8* %m + ret void +} + +define i8* @test_1() { +; CHECK-LABEL: @test_1( + %m = call i8* @malloc(i32 24) + tail call void @f() [ "unknown"(i8* %m) ] + store i8 -19, i8* %m + tail call void @f() + store i8 101, i8* %m + +; CHECK: tail call void @f() [ "unknown"(i8* %m) ] +; CHECK: store i8 -19, i8* %m +; CHECK: tail call void @f() +; CHECK: store i8 101, i8* %m + + ret i8* %m +} + +define void @test_2() { +; Since the deopt operand bundle does not escape %m (see caveat below), it is +; legal to elide the final store that location. + +; CHECK-LABEL: @test_2( + %m = call i8* @malloc(i32 24) + tail call void @f() [ "deopt"(i8* %m) ] + store i8 -19, i8* %m + ret void + +; CHECK: tail call void @f() [ "deopt"(i8* %m) ] +; CHECK-NEXT ret void +} + +define i8* @test_3() { +; Since the deopt operand bundle does not escape %m (see caveat below), @f +; cannot observe the stores to %m + +; CHECK-LABEL: @test_3( + %m = call i8* @malloc(i32 24) + tail call void @f() [ "deopt"(i8* %m) ] + store i8 -19, i8* %m + tail call void @f() + store i8 101, i8* %m + ret i8* %m +} + + +; Caveat: technically, %m can only escape if the calling function is deoptimized +; at the call site (i.e. the call returns to the "deopt" continuation). Since +; the calling function body will be invalidated in that case, the calling +; function can be optimized under the assumption that %m does not escape. diff --git a/test/Feature/OperandBundles/early-cse.ll b/test/Feature/OperandBundles/early-cse.ll new file mode 100644 index 000000000000..fc201479d8ce --- /dev/null +++ b/test/Feature/OperandBundles/early-cse.ll @@ -0,0 +1,89 @@ +; RUN: opt -S -early-cse < %s | FileCheck %s + +; While it is normally okay to do memory optimizations over calls to +; @readonly_function and @readnone_function, we cannot do that if +; they're carrying unknown operand bundles since the presence of +; unknown operand bundles implies arbitrary memory effects. + +declare void @readonly_function() readonly nounwind +declare void @readnone_function() readnone nounwind + +define i32 @test0(i32* %x) { +; CHECK-LABEL: @test0( + entry: + store i32 100, i32* %x +; CHECK: store i32 100, i32* %x + call void @readonly_function() [ "tag"() ] +; CHECK: call void @readonly_function() + + %v = load i32, i32* %x +; CHECK: %v = load i32, i32* %x +; CHECK: ret i32 %v + ret i32 %v +} + +define i32 @test1(i32* %x) { +; CHECK: @test1( + entry: + store i32 100, i32* %x +; CHECK: store i32 100, i32* %x + call void @readonly_function() readonly [ "tag"() ] +; CHECK-NOT: call void @readonly_function + %v = load i32, i32* %x + ret i32 %v +; CHECK: ret i32 100 +} + +define i32 @test3(i32* %x) { +; CHECK-LABEL: @test3( + entry: + store i32 100, i32* %x +; CHECK: store i32 100, i32* %x + call void @readonly_function() +; CHECK-NOT: call void @readonly_function + %v = load i32, i32* %x + ret i32 %v +; CHECK: ret i32 100 +} + +define void @test4(i32* %x) { +; CHECK-LABEL: @test4( + entry: + store i32 100, i32* %x +; CHECK: store i32 100, i32* %x + call void @readnone_function() [ "tag"() ] +; CHECK: call void @readnone_function + store i32 200, i32* %x +; CHECK: store i32 200, i32* %x + ret void +} + +define void @test5(i32* %x) { +; CHECK-LABEL: @test5( + entry: + store i32 100, i32* %x +; CHECK-NOT: store i32 100, i32* %x +; CHECK-NOT: call void @readnone_function + call void @readnone_function() readnone [ "tag"() ] + store i32 200, i32* %x +; CHECK: store i32 200, i32* %x + ret void +} + +define void @test6(i32* %x) { +; The "deopt" operand bundle does not make the call to +; @readonly_function read-write; and so the nounwind readonly call can +; be deleted. + +; CHECK-LABEL: @test6( + entry: + +; CHECK-NEXT: entry: +; CHECK-NEXT: store i32 200, i32* %x +; CHECK-NEXT: ret void + + store i32 100, i32* %x + call void @readonly_function() [ "deopt"() ] + store i32 200, i32* %x + ret void +} diff --git a/test/Feature/OperandBundles/function-attrs.ll b/test/Feature/OperandBundles/function-attrs.ll new file mode 100644 index 000000000000..808f396fed8b --- /dev/null +++ b/test/Feature/OperandBundles/function-attrs.ll @@ -0,0 +1,33 @@ +; RUN: opt -S -functionattrs < %s | FileCheck %s + +declare void @f_readonly() readonly +declare void @f_readnone() readnone + +define void @test_0(i32* %x) { +; FunctionAttrs must not infer readonly / readnone for %x + +; CHECK-LABEL: define void @test_0(i32* %x) { + entry: + ; CHECK: call void @f_readonly() [ "foo"(i32* %x) ] + call void @f_readonly() [ "foo"(i32* %x) ] + ret void +} + +define void @test_1(i32* %x) { +; FunctionAttrs must not infer readonly / readnone for %x + +; CHECK-LABEL: define void @test_1(i32* %x) { + entry: + ; CHECK: call void @f_readnone() [ "foo"(i32* %x) ] + call void @f_readnone() [ "foo"(i32* %x) ] + ret void +} + +define void @test_2(i32* %x) { +; The "deopt" operand bundle does not capture or write to %x. + +; CHECK-LABEL: define void @test_2(i32* nocapture readonly %x) + entry: + call void @f_readonly() [ "deopt"(i32* %x) ] + ret void +} diff --git a/test/Feature/OperandBundles/inliner-conservative.ll b/test/Feature/OperandBundles/inliner-conservative.ll new file mode 100644 index 000000000000..d9f09f71d905 --- /dev/null +++ b/test/Feature/OperandBundles/inliner-conservative.ll @@ -0,0 +1,17 @@ +; RUN: opt -S -inline < %s | FileCheck %s + +; Check that the inliner does not inline through arbitrary unknown +; operand bundles. + +define i32 @callee() { + entry: + ret i32 2 +} + +define i32 @caller() { +; CHECK: @caller( + entry: +; CHECK: call i32 @callee() [ "unknown"() ] + %x = call i32 @callee() [ "unknown"() ] + ret i32 %x +} diff --git a/test/Feature/OperandBundles/merge-func.ll b/test/Feature/OperandBundles/merge-func.ll new file mode 100644 index 000000000000..1fa6eb093084 --- /dev/null +++ b/test/Feature/OperandBundles/merge-func.ll @@ -0,0 +1,64 @@ +; RUN: opt -S -mergefunc < %s | FileCheck %s + +; Minor note: functions need to be at least three instructions long +; to be considered by -mergefunc. + +declare i32 @foo(...) + +define i32 @f() { +; CHECK-LABEL: @f( + entry: + %v0 = call i32 (...) @foo(i32 10) [ "foo"(i32 20) ] + %v1 = call i32 (...) @foo(i32 10) [ "foo"(i32 20) ] + %v2 = call i32 (...) @foo(i32 10) [ "foo"(i32 20) ] + +; CHECK: %v0 = call i32 (...) @foo(i32 10) [ "foo"(i32 20) ] +; CHECK: %v1 = call i32 (...) @foo(i32 10) [ "foo"(i32 20) ] +; CHECK: %v2 = call i32 (...) @foo(i32 10) [ "foo"(i32 20) ] + + ret i32 %v2 +} + +define i32 @g() { +; CHECK-LABEL: @g( + entry: + %v0 = call i32 (...) @foo() [ "foo"(i32 10, i32 20) ] + %v1 = call i32 (...) @foo() [ "foo"(i32 10, i32 20) ] + %v2 = call i32 (...) @foo() [ "foo"(i32 10, i32 20) ] + +; CHECK: %v0 = call i32 (...) @foo() [ "foo"(i32 10, i32 20) ] +; CHECK: %v1 = call i32 (...) @foo() [ "foo"(i32 10, i32 20) ] +; CHECK: %v2 = call i32 (...) @foo() [ "foo"(i32 10, i32 20) ] + + ret i32 %v2 +} + +define i32 @f.invoke() personality i8 3 { +; CHECK-LABEL: @f.invoke( + entry: +; CHECK: %v0 = invoke i32 (...) @foo(i32 10) [ "foo"(i32 20) ] + %v0 = invoke i32 (...) @foo(i32 10) [ "foo"(i32 20) ] + to label %normal unwind label %exception + + normal: + ret i32 %v0 + + exception: + %cleanup = landingpad i8 cleanup + ret i32 0 +} + +define i32 @g.invoke() personality i8 3 { +; CHECK-LABEL: @g.invoke( + entry: +; CHECK: %v0 = invoke i32 (...) @foo() [ "foo"(i32 10, i32 20) ] + %v0 = invoke i32 (...) @foo() [ "foo"(i32 10, i32 20) ] + to label %normal unwind label %exception + + normal: + ret i32 %v0 + + exception: + %cleanup = landingpad i8 cleanup + ret i32 0 +} diff --git a/test/Feature/OperandBundles/special-state.ll b/test/Feature/OperandBundles/special-state.ll new file mode 100644 index 000000000000..56e337cc16b3 --- /dev/null +++ b/test/Feature/OperandBundles/special-state.ll @@ -0,0 +1,21 @@ +; RUN: opt -S -early-cse < %s | FileCheck %s + +; This test isn't directly related to EarlyCSE or varargs. It is just +; using these as a vehicle for testing the correctness of +; haveSameSpecialState around operand bundles. + +declare i32 @foo(...) + +define i32 @f() { +; CHECK-LABEL: @f( + entry: +; CHECK: %v0 = call i32 (...) @foo( +; CHECK: %v1 = call i32 (...) @foo( +; CHECK: %v = add i32 %v0, %v1 +; CHECK: ret i32 %v + + %v0 = call i32 (...) @foo(i32 10) readonly [ "foo"(i32 20) ] + %v1 = call i32 (...) @foo() readonly [ "foo"(i32 10, i32 20) ] + %v = add i32 %v0, %v1 + ret i32 %v +} diff --git a/test/Feature/alias2.ll b/test/Feature/alias2.ll index e461854e7514..ae5bc11d71a9 100644 --- a/test/Feature/alias2.ll +++ b/test/Feature/alias2.ll @@ -9,20 +9,20 @@ @v3 = global [2 x i16] zeroinitializer ; CHECK: @v3 = global [2 x i16] zeroinitializer -@a1 = alias bitcast (i32* @v1 to i16*) -; CHECK: @a1 = alias bitcast (i32* @v1 to i16*) +@a1 = alias i16, bitcast (i32* @v1 to i16*) +; CHECK: @a1 = alias i16, bitcast (i32* @v1 to i16*) -@a2 = alias bitcast([1 x i32]* @v2 to i32*) -; CHECK: @a2 = alias getelementptr inbounds ([1 x i32], [1 x i32]* @v2, i32 0, i32 0) +@a2 = alias i32, bitcast([1 x i32]* @v2 to i32*) +; CHECK: @a2 = alias i32, getelementptr inbounds ([1 x i32], [1 x i32]* @v2, i32 0, i32 0) -@a3 = alias addrspacecast (i32* @v1 to i32 addrspace(2)*) -; CHECK: @a3 = alias addrspacecast (i32* @v1 to i32 addrspace(2)*) +@a3 = alias i32, addrspacecast (i32* @v1 to i32 addrspace(2)*) +; CHECK: @a3 = alias i32, addrspacecast (i32* @v1 to i32 addrspace(2)*) -@a4 = alias bitcast (i32* @v1 to i16*) -; CHECK: @a4 = alias bitcast (i32* @v1 to i16*) +@a4 = alias i16, bitcast (i32* @v1 to i16*) +; CHECK: @a4 = alias i16, bitcast (i32* @v1 to i16*) -@a5 = thread_local(localdynamic) alias i32* @v1 -; CHECK: @a5 = thread_local(localdynamic) alias i32* @v1 +@a5 = thread_local(localdynamic) alias i32, i32* @v1 +; CHECK: @a5 = thread_local(localdynamic) alias i32, i32* @v1 -@a6 = alias getelementptr ([2 x i16], [2 x i16]* @v3, i32 1, i32 1) -; CHECK: @a6 = alias getelementptr ([2 x i16], [2 x i16]* @v3, i32 1, i32 1) +@a6 = alias i16, getelementptr ([2 x i16], [2 x i16]* @v3, i32 1, i32 1) +; CHECK: @a6 = alias i16, getelementptr ([2 x i16], [2 x i16]* @v3, i32 1, i32 1) diff --git a/test/Feature/aliases.ll b/test/Feature/aliases.ll index b3b9ceba527b..a8c95e9fd0c3 100644 --- a/test/Feature/aliases.ll +++ b/test/Feature/aliases.ll @@ -5,28 +5,28 @@ @llvm.used = appending global [1 x i8*] [i8* bitcast (i32* @foo1 to i8*)], section "llvm.metadata" @bar = global i32 0 -@foo1 = alias i32* @bar -@foo2 = alias i32* @bar -@foo3 = alias i32* @foo2 -@foo4 = unnamed_addr alias i32* @foo2 +@foo1 = alias i32, i32* @bar +@foo2 = alias i32, i32* @bar +@foo3 = alias i32, i32* @foo2 +@foo4 = unnamed_addr alias i32, i32* @foo2 ; Make sure the verifier does not complain about references to a global ; declaration from an initializer. @decl = external global i32 @ptr = global i32* @decl -@ptr_a = alias i32** @ptr +@ptr_a = alias i32*, i32** @ptr %FunTy = type i32() define i32 @foo_f() { ret i32 0 } -@bar_f = weak_odr alias %FunTy* @foo_f -@bar_ff = alias i32()* @bar_f +@bar_f = weak_odr alias %FunTy, %FunTy* @foo_f +@bar_ff = alias i32(), i32()* @bar_f -@bar_i = internal alias i32* @bar +@bar_i = internal alias i32, i32* @bar -@A = alias bitcast (i32* @bar to i64*) +@A = alias i64, bitcast (i32* @bar to i64*) define i32 @test() { entry: diff --git a/test/Feature/callingconventions.ll b/test/Feature/callingconventions.ll index 9aafb36c7573..ac4c5090a51d 100644 --- a/test/Feature/callingconventions.ll +++ b/test/Feature/callingconventions.ll @@ -59,4 +59,11 @@ define void @ghc_caller() { ret void } +declare hhvm_ccc void @hhvm_c_callee() + +define hhvmcc void @hhvm_caller() { + call hhvm_ccc void @hhvm_c_callee() + ret void +} + declare i32 @__gxx_personality_v0(...) diff --git a/test/Feature/comdat.ll b/test/Feature/comdat.ll index c2a9d6396293..b0286c06ea0f 100644 --- a/test/Feature/comdat.ll +++ b/test/Feature/comdat.ll @@ -9,8 +9,8 @@ $f2 = comdat any @v = global i32 0, comdat($f) ; CHECK: @v = global i32 0, comdat($f) -@a = alias i32* @v -; CHECK: @a = alias i32* @v{{$}} +@a = alias i32, i32* @v +; CHECK: @a = alias i32, i32* @v{{$}} define void @f() comdat($f) { ret void diff --git a/test/Feature/exception.ll b/test/Feature/exception.ll index 7568ecfa5f75..2634692f4252 100644 --- a/test/Feature/exception.ll +++ b/test/Feature/exception.ll @@ -25,3 +25,112 @@ lpad: ; preds = %entry declare void @_Z3quxv() optsize declare i32 @__gxx_personality_v0(...) + +define void @cleanupret0() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %pad +pad: + %cp = cleanuppad within none [i7 4] + cleanupret from %cp unwind to caller +exit: + ret void +} + +; forward ref by name +define void @cleanupret1() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %pad +cleanup: + cleanupret from %cp unwind label %pad +pad: + %cp = cleanuppad within none [] + br label %cleanup +exit: + ret void +} + +; forward ref by ID +define void @cleanupret2() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %pad +cleanup: + cleanupret from %0 unwind label %pad +pad: + %0 = cleanuppad within none [] + br label %cleanup +exit: + ret void +} + +define void @catchret0() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %pad +pad: + %cs1 = catchswitch within none [label %catch] unwind to caller +catch: + %cp = catchpad within %cs1 [i7 4] + catchret from %cp to label %exit +exit: + ret void +} + +; forward ref by name +define void @catchret1() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %pad +catchret: + catchret from %cp to label %exit +pad: + %cs1 = catchswitch within none [label %catch] unwind to caller +catch: + %cp = catchpad within %cs1 [i7 4] + br label %catchret +exit: + ret void +} + +; forward ref by ID +define void @catchret2() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %pad +catchret: + catchret from %0 to label %exit +pad: + %cs1 = catchswitch within none [label %catch] unwind to caller +catch: + %0 = catchpad within %cs1 [i7 4] + br label %catchret +exit: + ret void +} + +define i8 @catchpad() personality i32 (...)* @__gxx_personality_v0 { +entry: + invoke void @_Z3quxv() optsize + to label %exit unwind label %bb2 +bb2: + %cs1 = catchswitch within none [label %catch] unwind to caller +catch: + catchpad within %cs1 [i7 4] + br label %exit +exit: + ret i8 0 +} + +define void @cleanuppad() personality i32 (...)* @__gxx_personality_v0 { +entry: + br label %try.cont + +try.cont: + invoke void @_Z3quxv() optsize + to label %try.cont unwind label %bb +bb: + cleanuppad within none [i7 4] + ret void +} diff --git a/test/Feature/optnone-llc.ll b/test/Feature/optnone-llc.ll index b848b19d528b..94f61efea4aa 100644 --- a/test/Feature/optnone-llc.ll +++ b/test/Feature/optnone-llc.ll @@ -3,11 +3,13 @@ ; RUN: llc -O2 -debug %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=LLC-Ox ; RUN: llc -O3 -debug %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=LLC-Ox ; RUN: llc -misched-postra -debug %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=LLC-MORE +; RUN: llc -O1 -debug-only=isel %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=FAST +; RUN: llc -O1 -debug-only=isel -fast-isel=false %s -o /dev/null 2>&1 | FileCheck %s --check-prefix=NOFAST -; REQUIRES: asserts +; REQUIRES: asserts, default_triple ; This test verifies that we don't run Machine Function optimizations -; on optnone functions. +; on optnone functions, and that we can turn off FastISel. ; Function Attrs: noinline optnone define i32 @_Z3fooi(i32 %x) #0 { @@ -52,3 +54,7 @@ attributes #0 = { optnone noinline } ; Alternate post-RA scheduler. ; LLC-MORE: Skipping pass 'PostRA Machine Instruction Scheduler' + +; Selectively disable FastISel for optnone functions. +; FAST: FastISel is enabled +; NOFAST: FastISel is disabled |
