[llvm] [SCEV] Append disjoint flag when mapping an Or instruction (PR #96208)

Anshil Gandhi via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 20 08:46:52 PDT 2024


https://github.com/gandhi56 created https://github.com/llvm/llvm-project/pull/96208

LoadStoreVectorizer appears to miss vectorizing opportunities because some of the `or` instructions missed the anticipated `disjoint` flag. This patch simply attempts to insert the disjoint flag immediately before converting the `or disjoint` into an `add`.

>From 446d28f44875f11982edc4f9dad459494a105a6d Mon Sep 17 00:00:00 2001
From: Anshil Gandhi <Anshil.Gandhi at amd.com>
Date: Thu, 20 Jun 2024 14:58:16 +0000
Subject: [PATCH] [SCEV] Append disjoint flag when mapping an Or instruction

LoadStoreVectorizer appears to miss vectorizing opportunities
because some of the or instructions missed the anticipated
disjoint flag. This patch simply attempts to insert the disjoint
flag immediately before converting the or disjoint into an add.

Change-Id: I8f228ca91c231cbb6ce67f354d3c11c448caf678
---
 llvm/lib/Analysis/ScalarEvolution.cpp                      | 7 ++++++-
 .../Transforms/Attributor/value-simplify-pointer-info.ll   | 4 ++--
 llvm/test/Transforms/LoopIdiom/remove-inserted-lcssa.ll    | 2 +-
 .../first-order-recurrence-multiply-recurrences.ll         | 2 +-
 4 files changed, 10 insertions(+), 5 deletions(-)

diff --git a/llvm/lib/Analysis/ScalarEvolution.cpp b/llvm/lib/Analysis/ScalarEvolution.cpp
index 9808308cbfed9..e88689dac9fce 100644
--- a/llvm/lib/Analysis/ScalarEvolution.cpp
+++ b/llvm/lib/Analysis/ScalarEvolution.cpp
@@ -5287,9 +5287,14 @@ static std::optional<BinaryOp> MatchBinaryOp(Value *V, const DataLayout &DL,
     return BinaryOp(Op);
 
   case Instruction::Or: {
+    auto *Op0 = Op->getOperand(0);
+    auto *Op1 = Op->getOperand(1);
+    if (haveNoCommonBitsSet(Op0, Op1, SimplifyQuery(DL, &DT, &AC, CxtI)))
+      cast<PossiblyDisjointInst>(Op)->setIsDisjoint(true);
+
     // Convert or disjoint into add nuw nsw.
     if (cast<PossiblyDisjointInst>(Op)->isDisjoint())
-      return BinaryOp(Instruction::Add, Op->getOperand(0), Op->getOperand(1),
+      return BinaryOp(Instruction::Add, Op0, Op1,
                       /*IsNSW=*/true, /*IsNUW=*/true);
     return BinaryOp(Op);
   }
diff --git a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
index 7a35b5c856097..870d8f03b6588 100644
--- a/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
+++ b/llvm/test/Transforms/Attributor/value-simplify-pointer-info.ll
@@ -285,7 +285,7 @@ define void @local_alloca_simplifiable_2() {
 ; TUNIT-NEXT:    br label [[FOR_END11:%.*]]
 ; TUNIT:       for.body5:
 ; TUNIT-NEXT:    [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
-; TUNIT-NEXT:    [[I18:%.*]] = or i64 [[I17]], 1
+; TUNIT-NEXT:    [[I18:%.*]] = or disjoint i64 [[I17]], 1
 ; TUNIT-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]]
 ; TUNIT-NEXT:    br label [[FOR_INC9]]
 ; TUNIT:       for.inc9:
@@ -360,7 +360,7 @@ define void @local_alloca_simplifiable_2() {
 ; CGSCC-NEXT:    br label [[FOR_END11:%.*]]
 ; CGSCC:       for.body5:
 ; CGSCC-NEXT:    [[I17:%.*]] = mul nuw nsw i64 [[INDVARS_IV2]], 10
-; CGSCC-NEXT:    [[I18:%.*]] = or i64 [[I17]], 1
+; CGSCC-NEXT:    [[I18:%.*]] = or disjoint i64 [[I17]], 1
 ; CGSCC-NEXT:    [[ARRAYIDX8:%.*]] = getelementptr inbounds float, ptr [[BYTES]], i64 [[I18]]
 ; CGSCC-NEXT:    store float 0.000000e+00, ptr [[ARRAYIDX8]], align 4, !tbaa [[TBAA18:![0-9]+]]
 ; CGSCC-NEXT:    br label [[FOR_INC9]]
diff --git a/llvm/test/Transforms/LoopIdiom/remove-inserted-lcssa.ll b/llvm/test/Transforms/LoopIdiom/remove-inserted-lcssa.ll
index b20f7bd333c70..a9bcc48913c58 100644
--- a/llvm/test/Transforms/LoopIdiom/remove-inserted-lcssa.ll
+++ b/llvm/test/Transforms/LoopIdiom/remove-inserted-lcssa.ll
@@ -13,7 +13,7 @@ define void @test() {
 ; CHECK-NEXT:    [[PHI:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ 1, [[LOOP_LATCH:%.*]] ]
 ; CHECK-NEXT:    br i1 false, label [[LOOP_EXIT2:%.*]], label [[LOOP_LATCH]]
 ; CHECK:       loop.latch:
-; CHECK-NEXT:    [[OR:%.*]] = or i64 [[PHI]], 4
+; CHECK-NEXT:    [[OR:%.*]] = or disjoint i64 [[PHI]], 4
 ; CHECK-NEXT:    br i1 false, label [[LOOP_EXIT:%.*]], label [[LOOP]]
 ; CHECK:       loop.exit:
 ; CHECK-NEXT:    [[OR_LCSSA:%.*]] = phi i64 [ [[OR]], [[LOOP_LATCH]] ]
diff --git a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-multiply-recurrences.ll b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-multiply-recurrences.ll
index 7e15f038114fd..5a66902b80a1e 100644
--- a/llvm/test/Transforms/LoopVectorize/first-order-recurrence-multiply-recurrences.ll
+++ b/llvm/test/Transforms/LoopVectorize/first-order-recurrence-multiply-recurrences.ll
@@ -181,7 +181,7 @@ define void @test_pr54227(ptr noalias %a, ptr noalias %b) {
 ; CHECK-NEXT:    [[OR:%.*]] = or i32 [[AND]], [[E_0]]
 ; CHECK-NEXT:    [[AND1]] = and i32 [[E_0]], [[F_0]]
 ; CHECK-NEXT:    [[MUL]] = shl nsw i32 [[OR]], 1
-; CHECK-NEXT:    [[ADD]] = or i32 [[AND1]], 1
+; CHECK-NEXT:    [[ADD]] = or disjoint i32 [[AND1]], 1
 ; CHECK-NEXT:    [[A_GEP:%.*]] = getelementptr inbounds i32, ptr [[A:%.*]], i64 [[IV]]
 ; CHECK-NEXT:    store i32 [[ADD]], ptr [[A_GEP]], align 4
 ; CHECK-NEXT:    [[B_GEP:%.*]] = getelementptr inbounds i32, ptr [[A]], i64 [[IV]]



More information about the llvm-commits mailing list