[llvm] d15b7a8 - [llvm][LICM] Limit multi-use BOAssociation to FP and Vector (#149829)
via llvm-commits
llvm-commits at lists.llvm.org
Thu Aug 14 03:56:58 PDT 2025
Author: Theodoros Theodoridis
Date: 2025-08-14T11:56:55+01:00
New Revision: d15b7a83a7e0b8a73763e24ad162a544a68ae74d
URL: https://github.com/llvm/llvm-project/commit/d15b7a83a7e0b8a73763e24ad162a544a68ae74d
DIFF: https://github.com/llvm/llvm-project/commit/d15b7a83a7e0b8a73763e24ad162a544a68ae74d.diff
LOG: [llvm][LICM] Limit multi-use BOAssociation to FP and Vector (#149829)
Limit the re-association of BOps with multiple users to FP and Vector
arithmetic.
Added:
Modified:
llvm/lib/Transforms/Scalar/LICM.cpp
llvm/test/CodeGen/PowerPC/p10-spill-crlt.ll
llvm/test/CodeGen/PowerPC/swaps-le-1.ll
llvm/test/Transforms/LICM/hoist-binop.ll
llvm/test/Transforms/LICM/sink-foldable.ll
llvm/test/Transforms/LICM/update-scev-after-hoist.ll
Removed:
################################################################################
diff --git a/llvm/lib/Transforms/Scalar/LICM.cpp b/llvm/lib/Transforms/Scalar/LICM.cpp
index 1ef4fcc5fac47..4c035a2464c84 100644
--- a/llvm/lib/Transforms/Scalar/LICM.cpp
+++ b/llvm/lib/Transforms/Scalar/LICM.cpp
@@ -2867,7 +2867,7 @@ static bool hoistBOAssociation(Instruction &I, Loop &L,
bool LVInRHS = L.isLoopInvariant(BO->getOperand(0));
auto *BO0 = dyn_cast<BinaryOperator>(BO->getOperand(LVInRHS));
if (!BO0 || BO0->getOpcode() != Opcode || !BO0->isAssociative() ||
- BO0->hasNUsesOrMore(3))
+ BO0->hasNUsesOrMore(BO0->getType()->isIntegerTy() ? 2 : 3))
return false;
Value *LV = BO0->getOperand(0);
diff --git a/llvm/test/CodeGen/PowerPC/p10-spill-crlt.ll b/llvm/test/CodeGen/PowerPC/p10-spill-crlt.ll
index c733a01950603..4b032781c3764 100644
--- a/llvm/test/CodeGen/PowerPC/p10-spill-crlt.ll
+++ b/llvm/test/CodeGen/PowerPC/p10-spill-crlt.ll
@@ -30,16 +30,14 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
; CHECK-NEXT: mflr r0
; CHECK-NEXT: std r0, 16(r1)
; CHECK-NEXT: stw r12, 8(r1)
-; CHECK-NEXT: stdu r1, -64(r1)
-; CHECK-NEXT: .cfi_def_cfa_offset 64
+; CHECK-NEXT: stdu r1, -48(r1)
+; CHECK-NEXT: .cfi_def_cfa_offset 48
; CHECK-NEXT: .cfi_offset lr, 16
-; CHECK-NEXT: .cfi_offset r29, -24
; CHECK-NEXT: .cfi_offset r30, -16
; CHECK-NEXT: .cfi_offset cr2, 8
; CHECK-NEXT: .cfi_offset cr3, 8
; CHECK-NEXT: .cfi_offset cr4, 8
-; CHECK-NEXT: std r29, 40(r1) # 8-byte Folded Spill
-; CHECK-NEXT: std r30, 48(r1) # 8-byte Folded Spill
+; CHECK-NEXT: std r30, 32(r1) # 8-byte Folded Spill
; CHECK-NEXT: bl call_2 at notoc
; CHECK-NEXT: bc 12, 4*cr5+lt, .LBB0_13
; CHECK-NEXT: # %bb.1: # %bb
@@ -67,11 +65,10 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
; CHECK-NEXT: bc 12, 4*cr3+eq, .LBB0_11
; CHECK-NEXT: # %bb.6: # %bb32
; CHECK-NEXT: #
+; CHECK-NEXT: rlwinm r30, r30, 0, 24, 22
; CHECK-NEXT: andi. r3, r30, 2
-; CHECK-NEXT: rlwinm r29, r30, 0, 24, 22
; CHECK-NEXT: mcrf cr2, cr0
; CHECK-NEXT: bl call_4 at notoc
-; CHECK-NEXT: mr r30, r29
; CHECK-NEXT: beq+ cr2, .LBB0_3
; CHECK-NEXT: # %bb.7: # %bb37
; CHECK-NEXT: .LBB0_8: # %bb22
@@ -92,13 +89,11 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
; CHECK-BE-NEXT: stdu r1, -144(r1)
; CHECK-BE-NEXT: .cfi_def_cfa_offset 144
; CHECK-BE-NEXT: .cfi_offset lr, 16
-; CHECK-BE-NEXT: .cfi_offset r28, -32
; CHECK-BE-NEXT: .cfi_offset r29, -24
; CHECK-BE-NEXT: .cfi_offset r30, -16
; CHECK-BE-NEXT: .cfi_offset cr2, 8
; CHECK-BE-NEXT: .cfi_offset cr2, 8
; CHECK-BE-NEXT: .cfi_offset cr2, 8
-; CHECK-BE-NEXT: std r28, 112(r1) # 8-byte Folded Spill
; CHECK-BE-NEXT: std r29, 120(r1) # 8-byte Folded Spill
; CHECK-BE-NEXT: std r30, 128(r1) # 8-byte Folded Spill
; CHECK-BE-NEXT: bl call_2
@@ -131,12 +126,11 @@ define dso_local void @P10_Spill_CR_LT() local_unnamed_addr {
; CHECK-BE-NEXT: bc 12, 4*cr3+eq, .LBB0_11
; CHECK-BE-NEXT: # %bb.6: # %bb32
; CHECK-BE-NEXT: #
+; CHECK-BE-NEXT: rlwinm r29, r29, 0, 24, 22
; CHECK-BE-NEXT: andi. r3, r29, 2
-; CHECK-BE-NEXT: rlwinm r28, r29, 0, 24, 22
; CHECK-BE-NEXT: mcrf cr2, cr0
; CHECK-BE-NEXT: bl call_4
; CHECK-BE-NEXT: nop
-; CHECK-BE-NEXT: mr r29, r28
; CHECK-BE-NEXT: beq+ cr2, .LBB0_3
; CHECK-BE-NEXT: # %bb.7: # %bb37
; CHECK-BE-NEXT: .LBB0_8: # %bb22
diff --git a/llvm/test/CodeGen/PowerPC/swaps-le-1.ll b/llvm/test/CodeGen/PowerPC/swaps-le-1.ll
index f3e34101efa29..5d5445f9f473a 100644
--- a/llvm/test/CodeGen/PowerPC/swaps-le-1.ll
+++ b/llvm/test/CodeGen/PowerPC/swaps-le-1.ll
@@ -187,34 +187,34 @@ define void @foo() {
; CHECK-P9-NEXT: .p2align 4
; CHECK-P9-NEXT: .LBB0_1: # %vector.body
; CHECK-P9-NEXT: #
-; CHECK-P9-NEXT: lxv 2, -32(6)
-; CHECK-P9-NEXT: lxv 3, -32(5)
-; CHECK-P9-NEXT: lxv 4, -16(5)
-; CHECK-P9-NEXT: vadduwm 2, 3, 2
+; CHECK-P9-NEXT: lxv 2, -32(3)
; CHECK-P9-NEXT: lxv 3, -32(4)
+; CHECK-P9-NEXT: lxv 4, -16(4)
+; CHECK-P9-NEXT: vadduwm 2, 3, 2
+; CHECK-P9-NEXT: lxv 3, -32(5)
; CHECK-P9-NEXT: vmuluwm 2, 2, 3
-; CHECK-P9-NEXT: lxv 3, -16(6)
-; CHECK-P9-NEXT: vadduwm 3, 4, 3
-; CHECK-P9-NEXT: lxv 4, 0(5)
-; CHECK-P9-NEXT: stxv 2, -32(3)
-; CHECK-P9-NEXT: lxv 2, -16(4)
-; CHECK-P9-NEXT: vmuluwm 2, 3, 2
-; CHECK-P9-NEXT: lxv 3, 0(6)
+; CHECK-P9-NEXT: lxv 3, -16(3)
; CHECK-P9-NEXT: vadduwm 3, 4, 3
-; CHECK-P9-NEXT: lxv 4, 16(5)
-; CHECK-P9-NEXT: addi 5, 5, 64
-; CHECK-P9-NEXT: stxv 2, -16(3)
-; CHECK-P9-NEXT: lxv 2, 0(4)
+; CHECK-P9-NEXT: lxv 4, 0(4)
+; CHECK-P9-NEXT: stxv 2, -32(6)
+; CHECK-P9-NEXT: lxv 2, -16(5)
; CHECK-P9-NEXT: vmuluwm 2, 3, 2
-; CHECK-P9-NEXT: lxv 3, 16(6)
-; CHECK-P9-NEXT: addi 6, 6, 64
+; CHECK-P9-NEXT: lxv 3, 0(3)
; CHECK-P9-NEXT: vadduwm 3, 4, 3
-; CHECK-P9-NEXT: stxv 2, 0(3)
-; CHECK-P9-NEXT: lxv 2, 16(4)
+; CHECK-P9-NEXT: lxv 4, 16(4)
; CHECK-P9-NEXT: addi 4, 4, 64
+; CHECK-P9-NEXT: stxv 2, -16(6)
+; CHECK-P9-NEXT: lxv 2, 0(5)
; CHECK-P9-NEXT: vmuluwm 2, 3, 2
-; CHECK-P9-NEXT: stxv 2, 16(3)
+; CHECK-P9-NEXT: lxv 3, 16(3)
; CHECK-P9-NEXT: addi 3, 3, 64
+; CHECK-P9-NEXT: vadduwm 3, 4, 3
+; CHECK-P9-NEXT: stxv 2, 0(6)
+; CHECK-P9-NEXT: lxv 2, 16(5)
+; CHECK-P9-NEXT: addi 5, 5, 64
+; CHECK-P9-NEXT: vmuluwm 2, 3, 2
+; CHECK-P9-NEXT: stxv 2, 16(6)
+; CHECK-P9-NEXT: addi 6, 6, 64
; CHECK-P9-NEXT: bdnz .LBB0_1
; CHECK-P9-NEXT: # %bb.2: # %for.end
; CHECK-P9-NEXT: blr
diff --git a/llvm/test/Transforms/LICM/hoist-binop.ll b/llvm/test/Transforms/LICM/hoist-binop.ll
index 1b1347776fb9e..724f45979f6ba 100644
--- a/llvm/test/Transforms/LICM/hoist-binop.ll
+++ b/llvm/test/Transforms/LICM/hoist-binop.ll
@@ -22,6 +22,31 @@ loop:
br label %loop
}
+; Don't hoist ADD if the op has more than one use.
+define void @add_two_uses(i64 %c1, i64 %c2) {
+; CHECK-LABEL: @add_two_uses(
+; CHECK-NEXT: entry:
+; CHECK-NEXT: br label [[LOOP:%.*]]
+; CHECK: loop:
+; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1:%.*]]
+; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT]] = add i64 [[STEP_ADD]], [[C2:%.*]]
+; CHECK-NEXT: call void @use(i64 [[INDEX_NEXT]])
+; CHECK-NEXT: br label [[LOOP]]
+;
+entry:
+ br label %loop
+
+loop:
+ %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
+ %step.add = add i64 %index, %c1
+ call void @use(i64 %step.add)
+ %index.next = add i64 %step.add, %c2
+ call void @use(i64 %index.next)
+ br label %loop
+}
+
; Hoist MUL and remove old op if unused.
define void @mul_one_use(i64 %c1, i64 %c2) {
; CHECK-LABEL: @mul_one_use(
@@ -51,8 +76,6 @@ define void @add_nuw(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -62,7 +85,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nuw i64 %step.add, %c2
br label %loop
}
@@ -76,8 +98,6 @@ define void @add_nuw_comm(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw i64 [[C1]], [[INDEX]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -87,7 +107,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw i64 %c1, %index
- call void @use(i64 %step.add)
%index.next = add nuw i64 %step.add, %c2
br label %loop
}
@@ -101,8 +120,6 @@ define void @add_nuw_comm2(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -112,7 +129,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nuw i64 %c2, %step.add
br label %loop
}
@@ -126,8 +142,6 @@ define void @add_nuw_comm3(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw i64 [[C1]], [[INDEX]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -137,7 +151,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw i64 %c1, %index
- call void @use(i64 %step.add)
%index.next = add nuw i64 %c2, %step.add
br label %loop
}
@@ -152,8 +165,6 @@ define void @add_nuw_twobinops(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw i64 [[C1]], [[INDEX]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -163,135 +174,134 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw i64 %c1, %index
- call void @use(i64 %step.add)
%c2.plus.2 = add nuw i64 %c2, 2
%index.next = add nuw i64 %step.add, %c2.plus.2
br label %loop
}
; Hoist MUL and drop NUW even if both ops have it.
-define void @mul_nuw(i64 %c1, i64 %c2) {
+define void @mul_nuw(<2 x i64> %c1, <2 x i64> %c2) {
; CHECK-LABEL: @mul_nuw(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul <2 x i64> [[C1:%.*]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
-; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: [[INDEX:%.*]] = phi <2 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw <2 x i64> [[INDEX]], [[C1]]
+; CHECK-NEXT: call void @use(<2 x i64> [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul <2 x i64> [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
- %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
- %step.add = mul nuw i64 %index, %c1
- call void @use(i64 %step.add)
- %index.next = mul nuw i64 %step.add, %c2
+ %index = phi <2 x i64> [ zeroinitializer, %entry ], [ %index.next, %loop ]
+ %step.add = mul nuw <2 x i64> %index, %c1
+ call void @use(<2 x i64> %step.add)
+ %index.next = mul nuw <2 x i64> %step.add, %c2
br label %loop
}
; Hoist MUL and drop NUW even if both ops have it.
; Version where operands are commuted.
-define void @mul_nuw_comm(i64 %c1, i64 %c2) {
+define void @mul_nuw_comm(<2 x i64> %c1, <2 x i64> %c2) {
; CHECK-LABEL: @mul_nuw_comm(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul <2 x i64> [[C1:%.*]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw i64 [[C1]], [[INDEX]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
-; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: [[INDEX:%.*]] = phi <2 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw <2 x i64> [[C1]], [[INDEX]]
+; CHECK-NEXT: call void @use(<2 x i64> [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul <2 x i64> [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
- %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
- %step.add = mul nuw i64 %c1, %index
- call void @use(i64 %step.add)
- %index.next = mul nuw i64 %step.add, %c2
+ %index = phi <2 x i64> [ zeroinitializer, %entry ], [ %index.next, %loop ]
+ %step.add = mul nuw <2 x i64> %c1, %index
+ call void @use(<2 x i64> %step.add)
+ %index.next = mul nuw <2 x i64> %step.add, %c2
br label %loop
}
; Hoist MUL and drop NUW even if both ops have it.
; Another version where operands are commuted.
-define void @mul_nuw_comm2(i64 %c1, i64 %c2) {
+define void @mul_nuw_comm2(<2 x i64> %c1, <2 x i64> %c2) {
; CHECK-LABEL: @mul_nuw_comm2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul <2 x i64> [[C1:%.*]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
-; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: [[INDEX:%.*]] = phi <2 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw <2 x i64> [[INDEX]], [[C1]]
+; CHECK-NEXT: call void @use(<2 x i64> [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul <2 x i64> [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
- %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
- %step.add = mul nuw i64 %index, %c1
- call void @use(i64 %step.add)
- %index.next = mul nuw i64 %c2, %step.add
+ %index = phi <2 x i64> [ zeroinitializer, %entry ], [ %index.next, %loop ]
+ %step.add = mul nuw <2 x i64> %index, %c1
+ call void @use(<2 x i64> %step.add)
+ %index.next = mul nuw <2 x i64> %c2, %step.add
br label %loop
}
; Hoist MUL and drop NUW even if both ops have it.
; Another version where operands are commuted.
-define void @mul_nuw_comm3(i64 %c1, i64 %c2) {
+define void @mul_nuw_comm3(<2 x i64> %c1, <2 x i64> %c2) {
; CHECK-LABEL: @mul_nuw_comm3(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul <2 x i64> [[C1:%.*]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw i64 [[C1]], [[INDEX]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
-; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: [[INDEX:%.*]] = phi <2 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw <2 x i64> [[C1]], [[INDEX]]
+; CHECK-NEXT: call void @use(<2 x i64> [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul <2 x i64> [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
- %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
- %step.add = mul nuw i64 %c1, %index
- call void @use(i64 %step.add)
- %index.next = mul nuw i64 %c2, %step.add
+ %index = phi <2 x i64> [ zeroinitializer, %entry ], [ %index.next, %loop ]
+ %step.add = mul nuw <2 x i64> %c1, %index
+ call void @use(<2 x i64> %step.add)
+ %index.next = mul nuw <2 x i64> %c2, %step.add
br label %loop
}
; Hoist MUL and drop NUW even if both ops have it.
; A version where the LHS and RHS of the outer BinOp are BinOps.
-define void @mul_nuw_twobinops(i64 %c1, i64 %c2) {
+define void @mul_nuw_twobinops(<2 x i64> %c1, <2 x i64> %c2) {
; CHECK-LABEL: @mul_nuw_twobinops(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[C2_PLUS_2:%.*]] = add nuw i64 [[C2:%.*]], 2
-; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul i64 [[C1:%.*]], [[C2_PLUS_2]]
+; CHECK-NEXT: [[C2_PLUS_2:%.*]] = add nuw <2 x i64> [[C2:%.*]], splat (i64 2)
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul <2 x i64> [[C1:%.*]], [[C2_PLUS_2]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw i64 [[C1]], [[INDEX]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
-; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: [[INDEX:%.*]] = phi <2 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nuw <2 x i64> [[C1]], [[INDEX]]
+; CHECK-NEXT: call void @use(<2 x i64> [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul <2 x i64> [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
- %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
- %step.add = mul nuw i64 %c1, %index
- call void @use(i64 %step.add)
- %c2.plus.2 = add nuw i64 %c2, 2
- %index.next = mul nuw i64 %step.add, %c2.plus.2
+ %index = phi <2 x i64> [ zeroinitializer, %entry ], [ %index.next, %loop ]
+ %step.add = mul nuw <2 x i64> %c1, %index
+ call void @use(<2 x i64> %step.add)
+ %c2.plus.2 = add nuw <2 x i64> %c2, <i64 2, i64 2>
+ %index.next = mul nuw <2 x i64> %step.add, %c2.plus.2
br label %loop
}
@@ -303,8 +313,6 @@ define void @add_no_nuw(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -314,7 +322,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nuw i64 %step.add, %c2
br label %loop
}
@@ -327,8 +334,6 @@ define void @add_no_nsw(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -338,7 +343,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nsw i64 %step.add, %c2
br label %loop
}
@@ -351,8 +355,6 @@ define void @add_no_nsw_2(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nsw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -362,7 +364,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nsw i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nsw i64 %step.add, %c2
br label %loop
}
@@ -375,8 +376,6 @@ define void @add_nuw_nsw(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw nsw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add nuw nsw i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -386,7 +385,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw nsw i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nuw nsw i64 %step.add, %c2
br label %loop
}
@@ -398,8 +396,6 @@ define void @add_both_nsw_first_nuw(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nuw nsw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -409,7 +405,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nuw nsw i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nsw i64 %step.add, %c2
br label %loop
}
@@ -421,8 +416,6 @@ define void @add_both_nsw_second_nuw(i64 %c1, i64 %c2) {
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = add nsw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT_REASS]] = add i64 [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -432,33 +425,32 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add nsw i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = add nuw nsw i64 %step.add, %c2
br label %loop
}
;
; Hoist MUL and drop NSW even if both ops have it.
-define void @mul_no_nsw_2(i64 %c1, i64 %c2) {
+define void @mul_no_nsw_2(<2 x i64> %c1, <2 x i64> %c2) {
; CHECK-LABEL: @mul_no_nsw_2(
; CHECK-NEXT: entry:
-; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul i64 [[C1:%.*]], [[C2:%.*]]
+; CHECK-NEXT: [[INVARIANT_OP:%.*]] = mul <2 x i64> [[C1:%.*]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP:%.*]]
; CHECK: loop:
-; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
-; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nsw i64 [[INDEX]], [[C1]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
-; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul i64 [[INDEX]], [[INVARIANT_OP]]
+; CHECK-NEXT: [[INDEX:%.*]] = phi <2 x i64> [ zeroinitializer, [[ENTRY:%.*]] ], [ [[INDEX_NEXT_REASS:%.*]], [[LOOP]] ]
+; CHECK-NEXT: [[STEP_ADD:%.*]] = mul nsw <2 x i64> [[INDEX]], [[C1]]
+; CHECK-NEXT: call void @use(<2 x i64> [[STEP_ADD]])
+; CHECK-NEXT: [[INDEX_NEXT_REASS]] = mul <2 x i64> [[INDEX]], [[INVARIANT_OP]]
; CHECK-NEXT: br label [[LOOP]]
;
entry:
br label %loop
loop:
- %index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
- %step.add = mul nsw i64 %index, %c1
- call void @use(i64 %step.add)
- %index.next = mul nsw i64 %step.add, %c2
+ %index = phi <2 x i64> [ zeroinitializer, %entry ], [ %index.next, %loop ]
+ %step.add = mul nsw <2 x i64> %index, %c1
+ call void @use(<2 x i64> %step.add)
+ %index.next = mul nsw <2 x i64> %step.add, %c2
br label %loop
}
@@ -470,7 +462,6 @@ define void @
diff _ops(i64 %c1, i64 %c2) {
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[STEP_ADD:%.*]] = add i64 [[INDEX]], [[C1:%.*]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT]] = mul i64 [[STEP_ADD]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -480,7 +471,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = add i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = mul i64 %step.add, %c2
br label %loop
}
@@ -493,7 +483,6 @@ define void @noassoc_ops(i64 %c1, i64 %c2) {
; CHECK: loop:
; CHECK-NEXT: [[INDEX:%.*]] = phi i64 [ 0, [[ENTRY:%.*]] ], [ [[INDEX_NEXT:%.*]], [[LOOP]] ]
; CHECK-NEXT: [[STEP_ADD:%.*]] = sub i64 [[INDEX]], [[C1:%.*]]
-; CHECK-NEXT: call void @use(i64 [[STEP_ADD]])
; CHECK-NEXT: [[INDEX_NEXT]] = sub i64 [[STEP_ADD]], [[C2:%.*]]
; CHECK-NEXT: br label [[LOOP]]
;
@@ -503,7 +492,6 @@ entry:
loop:
%index = phi i64 [ 0, %entry ], [ %index.next, %loop ]
%step.add = sub i64 %index, %c1
- call void @use(i64 %step.add)
%index.next = sub i64 %step.add, %c2
br label %loop
}
diff --git a/llvm/test/Transforms/LICM/sink-foldable.ll b/llvm/test/Transforms/LICM/sink-foldable.ll
index d1cf3de5301b2..59dea58a6adee 100644
--- a/llvm/test/Transforms/LICM/sink-foldable.ll
+++ b/llvm/test/Transforms/LICM/sink-foldable.ll
@@ -97,7 +97,7 @@ define ptr @test2(i32 %j, ptr readonly %P, ptr readnone %Q) {
; CHECK-NEXT: [[ARRAYIDX2:%.*]] = getelementptr inbounds ptr, ptr [[ADD_PTR]], i64 [[IDX2_EXT]]
; CHECK-NEXT: [[L1:%.*]] = load ptr, ptr [[ARRAYIDX2]], align 8
; CHECK-NEXT: [[CMP2:%.*]] = icmp ugt ptr [[L1]], [[Q]]
-; CHECK-NEXT: [[ADD_REASS]] = add i32 [[I_ADDR]], 2
+; CHECK-NEXT: [[ADD_REASS]] = add nsw i32 [[ADD_I]], 1
; CHECK-NEXT: br i1 [[CMP2]], label [[LOOPEXIT2:%.*]], label [[FOR_COND]]
; CHECK: loopexit0:
; CHECK-NEXT: [[P0:%.*]] = phi ptr [ null, [[FOR_COND]] ]
diff --git a/llvm/test/Transforms/LICM/update-scev-after-hoist.ll b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
index e303d04ce3191..8f9045350813a 100644
--- a/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
+++ b/llvm/test/Transforms/LICM/update-scev-after-hoist.ll
@@ -4,7 +4,7 @@
define i16 @main() {
; SCEV-EXPR-LABEL: 'main'
; SCEV-EXPR-NEXT: Classifying expressions for: @main
-; SCEV-EXPR-NEXT: %mul = phi i16 [ 1, %entry ], [ %mul.n.3.reass, %loop ]
+; SCEV-EXPR-NEXT: %mul = phi i16 [ 1, %entry ], [ %mul.n.3, %loop ]
; SCEV-EXPR-NEXT: --> %mul U: [0,-15) S: [-32768,32753) Exits: 4096 LoopDispositions: { %loop: Variant }
; SCEV-EXPR-NEXT: %div = phi i16 [ 32767, %entry ], [ %div.n.3, %loop ]
; SCEV-EXPR-NEXT: --> %div U: [-2048,-32768) S: [-2048,-32768) Exits: 7 LoopDispositions: { %loop: Variant }
@@ -16,7 +16,7 @@ define i16 @main() {
; SCEV-EXPR-NEXT: --> %div.n.1 U: [-8192,8192) S: [-8192,8192) Exits: 1 LoopDispositions: { %loop: Variant }
; SCEV-EXPR-NEXT: %div.n.2 = sdiv i16 %div.n.1, 2
; SCEV-EXPR-NEXT: --> %div.n.2 U: [-4096,4096) S: [-4096,4096) Exits: 0 LoopDispositions: { %loop: Variant }
-; SCEV-EXPR-NEXT: %mul.n.3.reass = mul i16 %mul, 16
+; SCEV-EXPR-NEXT: %mul.n.3 = mul i16 %mul.n.reass.reass, 2
; SCEV-EXPR-NEXT: --> (16 * %mul) U: [0,-15) S: [-32768,32753) Exits: 0 LoopDispositions: { %loop: Variant }
; SCEV-EXPR-NEXT: %div.n.3 = sdiv i16 %div.n.2, 2
; SCEV-EXPR-NEXT: --> %div.n.3 U: [-2048,2048) S: [-2048,2048) Exits: 0 LoopDispositions: { %loop: Variant }
More information about the llvm-commits
mailing list