[PATCH] D85092: Peephole optimization for icmp (urem X, Y), X

Xavier Denis via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Sun Aug 2 04:43:55 PDT 2020


xldenis created this revision.
xldenis added reviewers: craig.topper, ctetreau, regehr.
Herald added subscribers: llvm-commits, JDevlieghere, hiraditya.
Herald added a project: LLVM.
xldenis requested review of this revision.

This revision adds the following peephole optimization and it's negation:

  %a = urem i64 %x, %y
  %b = icmp ule i64 %a, %x
  
  ====>
  %b = true

This pattern occurs in the bound checks of Rust code, the program

  const N: usize = 3;
  const T = u8;
  
  pub fn split_mutiple(slice: &[T]) -> (&[T], &[T]) {
      let len = slice.len() / N;
      slice.split_at(len * N)
  }

the method call `slice.split_at` will check that `len * N` is within the bounds of `slice`, this bounds check is after some transformations turned into the `urem` seen above and then LLVM fails to optimize it any further. Adding this optimization would cause this bounds check to be fully optimized away.

ref: https://github.com/rust-lang/rust/issues/74938


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D85092

Files:
  llvm/lib/Analysis/InstructionSimplify.cpp
  llvm/test/Transforms/InstSimplify/compare.ll


Index: llvm/test/Transforms/InstSimplify/compare.ll
===================================================================
--- llvm/test/Transforms/InstSimplify/compare.ll
+++ llvm/test/Transforms/InstSimplify/compare.ll
@@ -723,6 +723,22 @@
   ret i1 %B
 }
 
+define i1 @urem8(i32 %X, i32 %Y) {
+  ; CHECK-LABEL: @urem8(
+  ; CHECK-NEXT: ret i1 true
+  %A = urem i32 %X, %Y
+  %B = icmp ule i32 %A, %Y
+  ret i1 %B
+}
+
+define i1 @urem9(i32 %X, i32 %Y) {
+  ; CHECK-LABEL: @urem9(
+  ; CHECK-NEXT: ret i1 false
+  %A = urem i32 %X, %Y
+  %B = icmp ugt i32 %A, %Y
+  ret i1 %B
+}
+
 ; PR9343 #15
 define i1 @srem2(i16 %X, i32 %Y) {
 ; CHECK-LABEL: @srem2(
Index: llvm/lib/Analysis/InstructionSimplify.cpp
===================================================================
--- llvm/lib/Analysis/InstructionSimplify.cpp
+++ llvm/lib/Analysis/InstructionSimplify.cpp
@@ -2964,6 +2964,14 @@
     }
   }
 
+  // icmp pred (urem Y, X), Y
+  if (LBO && match(LBO, m_URem(m_Specific(RHS), m_Value()))) {
+    if (Pred == ICmpInst::ICMP_ULE)
+      return getTrue(ITy);
+    if (Pred == ICmpInst::ICMP_UGT)
+      return getFalse(ITy);
+  }
+
   // x >> y <=u x
   // x udiv y <=u x.
   if (LBO && (match(LBO, m_LShr(m_Specific(RHS), m_Value())) ||


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D85092.282440.patch
Type: text/x-patch
Size: 1239 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20200802/d7ac1d57/attachment.bin>


More information about the llvm-commits mailing list