Skip to content

Commit 99eddfc

Browse files
[EVM] Fold signextend(b, signextend(b, x)) -> signextend(b, x)
Implement instCombineIntrinsic in TTI and do the folding. Doing this early in the pipeline, we give LLVM opportunity to do more optimizations. Signed-off-by: Vladimir Radosavljevic <[email protected]>
1 parent 908334c commit 99eddfc

File tree

3 files changed

+28
-4
lines changed

3 files changed

+28
-4
lines changed

llvm/lib/Target/EVM/EVMTargetTransformInfo.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,33 @@
1212
//===----------------------------------------------------------------------===//
1313

1414
#include "EVMTargetTransformInfo.h"
15+
#include "llvm/IR/IntrinsicsEVM.h"
16+
#include "llvm/Transforms/InstCombine/InstCombiner.h"
1517
using namespace llvm;
18+
using namespace llvm::PatternMatch;
1619

1720
#define DEBUG_TYPE "evmtti"
1821

22+
static std::optional<Instruction *> instCombineSignExtend(InstCombiner &IC,
23+
IntrinsicInst &II) {
24+
// Fold signextend(b, signextend(b, x)) -> signextend(b, x)
25+
Value *B = nullptr, *X = nullptr;
26+
if (match(&II, m_Intrinsic<Intrinsic::evm_signextend>(
27+
m_Value(B), m_Intrinsic<Intrinsic::evm_signextend>(
28+
m_Deferred(B), m_Value(X)))))
29+
return IC.replaceInstUsesWith(II, II.getArgOperand(1));
30+
31+
return std::nullopt;
32+
}
33+
34+
std::optional<Instruction *>
35+
EVMTTIImpl::instCombineIntrinsic(InstCombiner &IC, IntrinsicInst &II) const {
36+
if (II.getIntrinsicID() == Intrinsic::evm_signextend)
37+
return instCombineSignExtend(IC, II);
38+
39+
return std::nullopt;
40+
}
41+
1942
unsigned EVMTTIImpl::getAssumedAddrSpace(const Value *V) const {
2043
const auto *LD = dyn_cast<LoadInst>(V);
2144
if (!LD)

llvm/lib/Target/EVM/EVMTargetTransformInfo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ class EVMTTIImpl final : public BasicTTIImplBase<EVMTTIImpl> {
4242
: BaseT(TM, F.getParent()->getDataLayout()), ST(TM->getSubtargetImpl(F)),
4343
TLI(ST->getTargetLowering()) {}
4444

45+
std::optional<Instruction *> instCombineIntrinsic(InstCombiner &IC,
46+
IntrinsicInst &II) const;
47+
4548
bool allowsMisalignedMemoryAccesses(LLVMContext &Context, unsigned BitWidth,
4649
unsigned AddressSpace = 0,
4750
Align Alignment = Align(1),

llvm/test/CodeGen/EVM/fold-signextend.ll

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,7 @@ define i256 @test_const(i256 %x) {
88
; CHECK-LABEL: define i256 @test_const(
99
; CHECK-SAME: i256 [[X:%.*]]) {
1010
; CHECK-NEXT: [[SIGNEXT1:%.*]] = call i256 @llvm.evm.signextend(i256 15, i256 [[X]])
11-
; CHECK-NEXT: [[SIGNEXT2:%.*]] = call i256 @llvm.evm.signextend(i256 15, i256 [[SIGNEXT1]])
12-
; CHECK-NEXT: ret i256 [[SIGNEXT2]]
11+
; CHECK-NEXT: ret i256 [[SIGNEXT1]]
1312
;
1413
%signext1 = call i256 @llvm.evm.signextend(i256 15, i256 %x)
1514
%signext2 = call i256 @llvm.evm.signextend(i256 15, i256 %signext1)
@@ -32,8 +31,7 @@ define i256 @test_var(i256 %b, i256 %x) {
3231
; CHECK-LABEL: define i256 @test_var(
3332
; CHECK-SAME: i256 [[B:%.*]], i256 [[X:%.*]]) {
3433
; CHECK-NEXT: [[SIGNEXT1:%.*]] = call i256 @llvm.evm.signextend(i256 [[B]], i256 [[X]])
35-
; CHECK-NEXT: [[SIGNEXT2:%.*]] = call i256 @llvm.evm.signextend(i256 [[B]], i256 [[SIGNEXT1]])
36-
; CHECK-NEXT: ret i256 [[SIGNEXT2]]
34+
; CHECK-NEXT: ret i256 [[SIGNEXT1]]
3735
;
3836
%signext1 = call i256 @llvm.evm.signextend(i256 %b, i256 %x)
3937
%signext2 = call i256 @llvm.evm.signextend(i256 %b, i256 %signext1)

0 commit comments

Comments
 (0)