[PATCH] D97665: [InstSimplify] Don't fold comparisons of non-inbounds GEPs

LemonBoy via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Mon May 10 12:27:37 PDT 2021


LemonBoy updated this revision to Diff 344148.
LemonBoy added a comment.

Rebased. I've moved the test to `icmp-null.ll` and made it a bit nicer.


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D97665/new/

https://reviews.llvm.org/D97665

Files:
  llvm/lib/IR/ConstantFold.cpp
  llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll


Index: llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll
+++ llvm/test/Transforms/InstSimplify/ConstProp/icmp-null.ll
@@ -119,7 +119,7 @@
 
 define i1 @null_gep_ne_null() {
 ; CHECK-LABEL: @null_gep_ne_null(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 icmp ne (i8* getelementptr (i8, i8* null, i64 ptrtoint (i32* @g2 to i64)), i8* null)
 ;
   %gep = getelementptr i8, i8* null, i64 ptrtoint (i32* @g2 to i64)
   %cmp = icmp ne i8* %gep, null
@@ -128,7 +128,7 @@
 
 define i1 @null_gep_ugt_null() {
 ; CHECK-LABEL: @null_gep_ugt_null(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 icmp ugt (i8* getelementptr (i8, i8* null, i64 ptrtoint (i32* @g2 to i64)), i8* null)
 ;
   %gep = getelementptr i8, i8* null, i64 ptrtoint (i32* @g2 to i64)
   %cmp = icmp ugt i8* %gep, null
@@ -146,7 +146,7 @@
 
 define i1 @null_gep_ne_global() {
 ; CHECK-LABEL: @null_gep_ne_global(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 icmp ne ([2 x i32]* getelementptr ([2 x i32], [2 x i32]* null, i64 ptrtoint (i32* @g2 to i64)), [2 x i32]* @g)
 ;
   %gep = getelementptr [2 x i32], [2 x i32]* null, i64 ptrtoint (i32* @g2 to i64)
   %cmp = icmp ne [2 x i32]* %gep, @g
@@ -155,7 +155,7 @@
 
 define i1 @null_gep_ult_global() {
 ; CHECK-LABEL: @null_gep_ult_global(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 icmp ult ([2 x i32]* getelementptr ([2 x i32], [2 x i32]* null, i64 ptrtoint (i32* @g2 to i64)), [2 x i32]* @g)
 ;
   %gep = getelementptr [2 x i32], [2 x i32]* null, i64 ptrtoint (i32* @g2 to i64)
   %cmp = icmp ult [2 x i32]* %gep, @g
@@ -200,7 +200,7 @@
 
 define i1 @global_gep_ugt_global_neg_offset() {
 ; CHECK-LABEL: @global_gep_ugt_global_neg_offset(
-; CHECK-NEXT:    ret i1 true
+; CHECK-NEXT:    ret i1 icmp ugt ([2 x i32]* getelementptr ([2 x i32], [2 x i32]* @g, i64 -1), [2 x i32]* @g)
 ;
   %gep = getelementptr [2 x i32], [2 x i32]* @g, i64 -1
   %cmp = icmp ugt [2 x i32]* %gep, @g
@@ -215,3 +215,25 @@
   %cmp = icmp sgt [2 x i32]* %gep, @g
   ret i1 %cmp
 }
+
+; The offset is negative and equal to the base pointer.
+
+define i1 @global_gep_eq_global_offset_neg() {
+; CHECK-LABEL: @global_gep_eq_global_offset_neg(
+; CHECK-NEXT:    ret i1 icmp eq ([2 x i32]* getelementptr ([2 x i32], [2 x i32]* @g, i64 sub (i64 0, i64 ptrtoint ([2 x i32]* @g to i64))), [2 x i32]* null)
+;
+  %off = sub i64 0, ptrtoint ([2 x i32]* @g to i64)
+  %gep = getelementptr [2 x i32], [2 x i32]* @g, i64 %off
+  %cmp = icmp eq [2 x i32]* %gep, null
+  ret i1 %cmp
+}
+
+define i1 @global_gep_ne_global_offset_neg() {
+; CHECK-LABEL: @global_gep_ne_global_offset_neg(
+; CHECK-NEXT:    ret i1 icmp ne ([2 x i32]* getelementptr ([2 x i32], [2 x i32]* @g, i64 sub (i64 0, i64 ptrtoint ([2 x i32]* @g to i64))), [2 x i32]* null)
+;
+  %off = sub i64 0, ptrtoint ([2 x i32]* @g to i64)
+  %gep = getelementptr [2 x i32], [2 x i32]* @g, i64 %off
+  %cmp = icmp ne [2 x i32]* %gep, null
+  ret i1 %cmp
+}
Index: llvm/lib/IR/ConstantFold.cpp
===================================================================
--- llvm/lib/IR/ConstantFold.cpp
+++ llvm/lib/IR/ConstantFold.cpp
@@ -1832,6 +1832,12 @@
 
     case Instruction::GetElementPtr: {
       GEPOperator *CE1GEP = cast<GEPOperator>(CE1);
+
+      // The foldings below assume the GEP to be inbounds.
+      // TODO: Some of the logic can be applied for non-inbounds GEPs as well.
+      if (!CE1GEP->isInBounds())
+        return ICmpInst::BAD_ICMP_PREDICATE;
+
       // Ok, since this is a getelementptr, we know that the constant has a
       // pointer type.  Check the various cases.
       if (isa<ConstantPointerNull>(V2)) {


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D97665.344148.patch
Type: text/x-patch
Size: 3743 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20210510/9c944a2e/attachment.bin>


More information about the llvm-commits mailing list