aboutsummaryrefslogtreecommitdiffstats
path: root/test/Transforms/InstSimplify/compare.ll
diff options
context:
space:
mode:
Diffstat (limited to 'test/Transforms/InstSimplify/compare.ll')
-rw-r--r--test/Transforms/InstSimplify/compare.ll35
1 files changed, 35 insertions, 0 deletions
diff --git a/test/Transforms/InstSimplify/compare.ll b/test/Transforms/InstSimplify/compare.ll
index 56627b9..0ecfb1f 100644
--- a/test/Transforms/InstSimplify/compare.ll
+++ b/test/Transforms/InstSimplify/compare.ll
@@ -647,3 +647,38 @@ unreachableblock:
%Y = icmp eq i32* %X, null
ret i1 %Y
}
+
+; It's not valid to fold a comparison of an argument with an alloca, even though
+; that's tempting. An argument can't *alias* an alloca, however the aliasing rule
+; relies on restrictions against guessing an object's address and dereferencing.
+; There are no restrictions against guessing an object's address and comparing.
+
+define i1 @alloca_argument_compare(i64* %arg) {
+ %alloc = alloca i64
+ %cmp = icmp eq i64* %arg, %alloc
+ ret i1 %cmp
+ ; CHECK: alloca_argument_compare
+ ; CHECK: ret i1 %cmp
+}
+
+; As above, but with the operands reversed.
+
+define i1 @alloca_argument_compare_swapped(i64* %arg) {
+ %alloc = alloca i64
+ %cmp = icmp eq i64* %alloc, %arg
+ ret i1 %cmp
+ ; CHECK: alloca_argument_compare_swapped
+ ; CHECK: ret i1 %cmp
+}
+
+; Don't assume that a noalias argument isn't equal to a global variable's
+; address. This is an example where AliasAnalysis' NoAlias concept is
+; different from actual pointer inequality.
+
+@y = external global i32
+define zeroext i1 @external_compare(i32* noalias %x) {
+ %cmp = icmp eq i32* %x, @y
+ ret i1 %cmp
+ ; CHECK: external_compare
+ ; CHECK: ret i1 %cmp
+}