diff options
author | Antonio Frighetto <me@antoniofrighetto.com> | 2025-06-27 19:03:46 +0200 |
---|---|---|
committer | Antonio Frighetto <me@antoniofrighetto.com> | 2025-06-27 19:04:28 +0200 |
commit | c11ea449e59cfbd10b7ba2ed11a049ca5184164a (patch) | |
tree | e9f0ef33a55025ca28229fd1716684f2e491cfcd /llvm/unittests/Analysis/ValueTrackingTest.cpp | |
parent | ac7e3910350aed59495883d4193275106047645f (diff) | |
download | llvm-c11ea449e59cfbd10b7ba2ed11a049ca5184164a.zip llvm-c11ea449e59cfbd10b7ba2ed11a049ca5184164a.tar.gz llvm-c11ea449e59cfbd10b7ba2ed11a049ca5184164a.tar.bz2 |
[ValueTracking] Add `matchSimpleBinaryIntrinsicRecurrence` helper
Similarly to what it is being done to match simple recurrence cycle
relations, attempt to match value-accumulating recurrences of kind:
```
%umax.acc = phi i8 [ %umax, %backedge ], [ %a, %entry ]
%umax = call i8 @llvm.umax.i8(i8 %umax.acc, i8 %b)
```
Preliminary work to let InstCombine avoid folding such recurrences,
so that simple loop-invariant computation may get hoisted. Minor
opportunity to refactor out code as well.
Diffstat (limited to 'llvm/unittests/Analysis/ValueTrackingTest.cpp')
-rw-r--r-- | llvm/unittests/Analysis/ValueTrackingTest.cpp | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/llvm/unittests/Analysis/ValueTrackingTest.cpp b/llvm/unittests/Analysis/ValueTrackingTest.cpp index 6031898..dbe7228 100644 --- a/llvm/unittests/Analysis/ValueTrackingTest.cpp +++ b/llvm/unittests/Analysis/ValueTrackingTest.cpp @@ -1257,6 +1257,58 @@ TEST_F(ValueTrackingTest, computePtrAlignment) { EXPECT_EQ(getKnownAlignment(A, DL, CxtI3, &AC, &DT), Align(16)); } +TEST_F(ValueTrackingTest, MatchBinaryIntrinsicRecurrenceUMax) { + auto M = parseModule(R"( + define i8 @test(i8 %a, i8 %b) { + entry: + br label %loop + loop: + %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ] + %umax.acc = phi i8 [ %umax, %loop ], [ %a, %entry ] + %umax = call i8 @llvm.umax.i8(i8 %umax.acc, i8 %b) + %iv.next = add nuw i8 %iv, 1 + %cmp = icmp ult i8 %iv.next, 10 + br i1 %cmp, label %loop, label %exit + exit: + ret i8 %umax + } + )"); + + auto *F = M->getFunction("test"); + auto *II = &cast<IntrinsicInst>(findInstructionByName(F, "umax")); + auto *UMaxAcc = &cast<PHINode>(findInstructionByName(F, "umax.acc")); + PHINode *PN; + Value *Init, *OtherOp; + EXPECT_TRUE(matchSimpleBinaryIntrinsicRecurrence(II, PN, Init, OtherOp)); + EXPECT_EQ(UMaxAcc, PN); + EXPECT_EQ(F->getArg(0), Init); + EXPECT_EQ(F->getArg(1), OtherOp); +} + +TEST_F(ValueTrackingTest, MatchBinaryIntrinsicRecurrenceNegativeFSHR) { + auto M = parseModule(R"( + define i8 @test(i8 %a, i8 %b, i8 %c) { + entry: + br label %loop + loop: + %iv = phi i8 [ %iv.next, %loop ], [ 0, %entry ] + %fshr.acc = phi i8 [ %fshr, %loop ], [ %a, %entry ] + %fshr = call i8 @llvm.fshr.i8(i8 %fshr.acc, i8 %b, i8 %c) + %iv.next = add nuw i8 %iv, 1 + %cmp = icmp ult i8 %iv.next, 10 + br i1 %cmp, label %loop, label %exit + exit: + ret i8 %fshr + } + )"); + + auto *F = M->getFunction("test"); + auto *II = &cast<IntrinsicInst>(findInstructionByName(F, "fshr")); + PHINode *PN; + Value *Init, *OtherOp; + EXPECT_FALSE(matchSimpleBinaryIntrinsicRecurrence(II, PN, Init, OtherOp)); +} + TEST_F(ComputeKnownBitsTest, ComputeKnownBits) { parseAssembly( "define i32 @test(i32 %a, i32 %b) {\n" |