[llvm] [LLVM]: Missed Optimization, treat the disjoint Or as an add (PR #86340)

Shourya Goel via llvm-commits llvm-commits at lists.llvm.org
Fri Mar 22 14:17:57 PDT 2024


https://github.com/Sh0g0-1758 created https://github.com/llvm/llvm-project/pull/86340

Fixes: #84401

>From 39a4a121b80a1e8d5c1cee738607e7fceec33211 Mon Sep 17 00:00:00 2001
From: Sh0g0-1758 <shouryagoel10000 at gmail.com>
Date: Fri, 22 Mar 2024 21:59:21 +0530
Subject: [PATCH] Initial commit

Added tests
---
 .../InstCombine/InstructionCombining.cpp      | 21 ++++++++++++-------
 .../Transforms/InstCombine/gep-disjoint.ll    | 21 +++++++++++++++++++
 2 files changed, 35 insertions(+), 7 deletions(-)
 create mode 100644 llvm/test/Transforms/InstCombine/gep-disjoint.ll

diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 7c40fb4fc86082..507d09077a5cca 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -2889,9 +2889,12 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
     // Try to replace ADD + GEP with GEP + GEP.
     Value *Idx1, *Idx2;
     if (match(GEP.getOperand(1),
-              m_OneUse(m_Add(m_Value(Idx1), m_Value(Idx2))))) {
+              m_OneUse(m_AddLike(m_Value(Idx1), m_Value(Idx2))))) {
       //   %idx = add i64 %idx1, %idx2
       //   %gep = getelementptr i32, ptr %ptr, i64 %idx
+      // or
+      //   %idx = or disjoint i64 %idx1, %idx2
+      //   %gep = getelementptr i32, ptr %ptr, i64 %idx
       // as:
       //   %newptr = getelementptr i32, ptr %ptr, i64 %idx1
       //   %newgep = getelementptr i32, ptr %newptr, i64 %idx2
@@ -2901,14 +2904,18 @@ Instruction *InstCombinerImpl::visitGetElementPtrInst(GetElementPtrInst &GEP) {
                                        Idx2);
     }
     ConstantInt *C;
-    if (match(GEP.getOperand(1), m_OneUse(m_SExtLike(m_OneUse(m_NSWAdd(
+    if (match(GEP.getOperand(1), m_OneUse(m_SExtLike(m_OneUse(m_NSWAddLike(
                                      m_Value(Idx1), m_ConstantInt(C))))))) {
-      // %add = add nsw i32 %idx1, idx2
-      // %sidx = sext i32 %add to i64
-      // %gep = getelementptr i32, ptr %ptr, i64 %sidx
+      //   %add = add nsw i32 %idx1, %idx2
+      //   %sidx = sext i32 %add to i64
+      //   %gep = getelementptr i32, ptr %ptr, i64 %sidx
+      // or
+      //   %disjointOr = or disjoint i32 %idx1, %idx2
+      //   %sidx = sext i32 %disjointOr to i64
+      //   %gep = getelementptr i32, ptr %ptr, i64 %sidx
       // as:
-      // %newptr = getelementptr i32, ptr %ptr, i32 %idx1
-      // %newgep = getelementptr i32, ptr %newptr, i32 idx2
+      //   %newptr = getelementptr i32, ptr %ptr, i32 %idx1
+      //   %newgep = getelementptr i32, ptr %newptr, i32 idx2
       auto *NewPtr = Builder.CreateGEP(
           GEP.getResultElementType(), GEP.getPointerOperand(),
           Builder.CreateSExt(Idx1, GEP.getOperand(1)->getType()));
diff --git a/llvm/test/Transforms/InstCombine/gep-disjoint.ll b/llvm/test/Transforms/InstCombine/gep-disjoint.ll
new file mode 100644
index 00000000000000..fe75519822963b
--- /dev/null
+++ b/llvm/test/Transforms/InstCombine/gep-disjoint.ll
@@ -0,0 +1,21 @@
+; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 4
+; RUN: opt < %s -passes=instcombine -S | FileCheck %s
+
+; test that when offset is know while indexing arrays
+; folding optimization takes place on the addition which gets folded into an OR
+
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+
+define ptr @test(ptr %arr, i32 %conv) {
+; CHECK-LABEL: define ptr @test(
+; CHECK-SAME: ptr [[ARR:%.*]], i32 [[CONV:%.*]]) {
+; CHECK-NEXT:    [[TMP1:%.*]] = sext i32 [[CONV]] to i64
+; CHECK-NEXT:    [[TMP2:%.*]] = getelementptr i8, ptr [[ARR]], i64 [[TMP1]]
+; CHECK-NEXT:    [[ARRAYIDX9:%.*]] = getelementptr i8, ptr [[TMP2]], i64 1
+; CHECK-NEXT:    ret ptr [[ARRAYIDX9]]
+;
+  %or7 = or disjoint i32 %conv, 1
+  %idxprom8 = zext nneg i32 %or7 to i64
+  %arrayidx9 = getelementptr i8, ptr %arr, i64 %idxprom8
+  ret ptr %arrayidx9
+}



More information about the llvm-commits mailing list