--- /dev/null
+; RUN: opt -S -basicaa -licm %s | FileCheck %s
+declare i32 @foo() readonly argmemonly nounwind
+declare i32 @foo2() readonly nounwind
+declare i32 @bar(i32* %loc2) readonly argmemonly nounwind
+
+define void @test(i32* %loc) {
+; CHECK-LABEL: @test
+; CHECK: @foo
+; CHECK-LABEL: loop:
+ br label %loop
+
+loop:
+ %res = call i32 @foo()
+ store i32 %res, i32* %loc
+ br label %loop
+}
+
+; Negative test: show argmemonly is required
+define void @test_neg(i32* %loc) {
+; CHECK-LABEL: @test_neg
+; CHECK-LABEL: loop:
+; CHECK: @foo
+ br label %loop
+
+loop:
+ %res = call i32 @foo2()
+ store i32 %res, i32* %loc
+ br label %loop
+}
+
+define void @test2(i32* noalias %loc, i32* noalias %loc2) {
+; CHECK-LABEL: @test2
+; CHECK: @bar
+; CHECK-LABEL: loop:
+ br label %loop
+
+loop:
+ %res = call i32 @bar(i32* %loc2)
+ store i32 %res, i32* %loc
+ br label %loop
+}
+
+; Negative test: %might clobber gep
+define void @test3(i32* %loc) {
+; CHECK-LABEL: @test3
+; CHECK-LABEL: loop:
+; CHECK: @bar
+ br label %loop
+
+loop:
+ %res = call i32 @bar(i32* %loc)
+ %gep = getelementptr i32, i32 *%loc, i64 1000000
+ store i32 %res, i32* %gep
+ br label %loop
+}
+
+
+; Negative test: %loc might alias %loc2
+define void @test4(i32* %loc, i32* %loc2) {
+; CHECK-LABEL: @test4
+; CHECK-LABEL: loop:
+; CHECK: @bar
+ br label %loop
+
+loop:
+ %res = call i32 @bar(i32* %loc2)
+ store i32 %res, i32* %loc
+ br label %loop
+}