From 9f7075de5c6200f4efda736220ca7716738a5e0e Mon Sep 17 00:00:00 2001 From: Philip Reames Date: Thu, 17 Feb 2022 12:00:44 -0800 Subject: [PATCH] {instsimplify] Precommit some tests for provable inequal pointers derived from allocas --- .../Transforms/InstSimplify/cmp-alloca-offsets.ll | 202 +++++++++++++++++++++ 1 file changed, 202 insertions(+) create mode 100644 llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll diff --git a/llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll b/llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll new file mode 100644 index 0000000..b59fee4 --- /dev/null +++ b/llvm/test/Transforms/InstSimplify/cmp-alloca-offsets.ll @@ -0,0 +1,202 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt < %s -passes=instsimplify -S | FileCheck %s +target datalayout = "p:32:32-p1:64:64" + +; This is a collection of tests checking whether we can prove pointers +; derived from two allocas as inequal *via offset checks*. Note that +; instcombine has alternate approaches (one cmp rule, and compare +; bases of common offset) that also handles these, but with different +; logic. + +; %a follows %b, derived equal +define i1 @adjacent_alloca() { +; CHECK-LABEL: @adjacent_alloca( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 4 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 0 + %b.off = getelementptr i8, i8* %b, i64 4 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; %b follows %a, derived equal +define i1 @adjacent_alloca2() { +; CHECK-LABEL: @adjacent_alloca2( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 4 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 4 + %b.off = getelementptr i8, i8* %b, i64 0 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; FIXME: Can't be equal +define i1 @positive_non_equal_end() { +; CHECK-LABEL: @positive_non_equal_end( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 4 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 4 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 4 + %b.off = getelementptr i8, i8* %b, i64 4 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; %b follows %a, derived equal +define i1 @positive_equal_past_end() { +; CHECK-LABEL: @positive_equal_past_end( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 8 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 12 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 8 + %b.off = getelementptr i8, i8* %b, i64 12 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +define i1 @positive_non_equal() { +; CHECK-LABEL: @positive_non_equal( +; CHECK-NEXT: ret i1 true +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 3 + %b.off = getelementptr i8, i8* %b, i64 3 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; %a follows %b, derived equal +define i1 @one_neg_equal1() { +; CHECK-LABEL: @one_neg_equal1( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 -1 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 3 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 -1 + %b.off = getelementptr i8, i8* %b, i64 3 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; %b follows %a, derived equal +define i1 @one_neg_equal2() { +; CHECK-LABEL: @one_neg_equal2( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 3 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 -1 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 3 + %b.off = getelementptr i8, i8* %b, i64 -1 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; %b follows %a, derived equal +define i1 @both_neg_equal() { +; CHECK-LABEL: @both_neg_equal( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 -4 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 -8 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 -4 + %b.off = getelementptr i8, i8* %b, i64 -8 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; FIXME: Can't be equal +define i1 @mixed_offsets1() { +; CHECK-LABEL: @mixed_offsets1( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 -1 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 2 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 -1 + %b.off = getelementptr i8, i8* %b, i64 2 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; FIXME: Can't be equal +define i1 @mixed_offsets2() { +; CHECK-LABEL: @mixed_offsets2( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 1 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 -2 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 1 + %b.off = getelementptr i8, i8* %b, i64 -2 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + +; FIXME: Can't be equal +define i1 @negative_in_other() { +; CHECK-LABEL: @negative_in_other( +; CHECK-NEXT: [[A:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[B:%.*]] = alloca i8, i32 4, align 1 +; CHECK-NEXT: [[A_OFF:%.*]] = getelementptr i8, i8* [[A]], i64 -3 +; CHECK-NEXT: [[B_OFF:%.*]] = getelementptr i8, i8* [[B]], i64 -2 +; CHECK-NEXT: [[RES:%.*]] = icmp ne i8* [[A_OFF]], [[B_OFF]] +; CHECK-NEXT: ret i1 [[RES]] +; + %a = alloca i8, i32 4 + %b = alloca i8, i32 4 + %a.off = getelementptr i8, i8* %a, i64 -3 + %b.off = getelementptr i8, i8* %b, i64 -2 + %res = icmp ne i8* %a.off, %b.off + ret i1 %res +} + + +attributes #0 = { null_pointer_is_valid } -- 2.7.4