Skip to content

Commit eceb24c

Browse files
authored
[RISCV] Hoist immediate addresses from loads/stores (llvm#83644)
In case of loads/stores from an immediate address, avoid rematerializing the constant for every block and allow consthoist to hoist it to the entry block.
1 parent 9e759f3 commit eceb24c

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

llvm/lib/Target/RISCV/RISCVTargetTransformInfo.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,14 @@ InstructionCost RISCVTTIImpl::getIntImmCostInst(unsigned Opcode, unsigned Idx,
165165
// split up large offsets in GEP into better parts than ConstantHoisting
166166
// can.
167167
return TTI::TCC_Free;
168+
case Instruction::Store:
169+
// If the address is a constant, use the materialization cost.
170+
if (Idx == 1)
171+
return getIntImmCost(Imm, Ty, CostKind);
172+
return TTI::TCC_Free;
173+
case Instruction::Load:
174+
// If the address is a constant, use the materialization cost.
175+
return getIntImmCost(Imm, Ty, CostKind);
168176
case Instruction::And:
169177
// zext.h
170178
if (Imm == UINT64_C(0xffff) && ST->hasStdExtZbb())

llvm/test/Transforms/ConstantHoisting/RISCV/immediates.ll

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,61 @@ define i64 @test16(i64 %a) nounwind {
150150
ret i64 %2
151151
}
152152

153+
; Check that we hoist the absolute address of the stores to the entry block.
154+
define void @test17(ptr %s, i32 %size) nounwind {
155+
; CHECK-LABEL: test17
156+
; CHECK: %const = bitcast i32 -1073741792 to i32
157+
; CHECK: %0 = inttoptr i32 %const to ptr
158+
; CHECK: store i32 20, ptr %0
159+
; CHECK: %1 = inttoptr i32 %const to ptr
160+
; CHECK: store i32 10, ptr %1
161+
entry:
162+
%cond = icmp eq i32 %size, 0
163+
br i1 %cond, label %if.true, label %exit
164+
if.true:
165+
store i32 20, ptr inttoptr (i32 -1073741792 to ptr)
166+
br label %exit
167+
exit:
168+
store i32 10, ptr inttoptr (i32 -1073741792 to ptr)
169+
ret void
170+
}
171+
172+
; Check that we hoist the absolute address of the loads to the entry block.
173+
define i32 @test18(ptr %s, i32 %size) nounwind {
174+
; CHECK-LABEL: test18
175+
; CHECK: %const = bitcast i32 -1073741792 to i32
176+
; CHECK: %0 = inttoptr i32 %const to ptr
177+
; CHECK: %1 = load i32, ptr %0
178+
; CHECK: %2 = inttoptr i32 %const to ptr
179+
; CHECK: %3 = load i32, ptr %2
180+
entry:
181+
%cond = icmp eq i32 %size, 0
182+
br i1 %cond, label %if.true, label %if.false
183+
if.true:
184+
%0 = load i32, ptr inttoptr (i32 -1073741792 to ptr)
185+
br label %return
186+
if.false:
187+
%1 = load i32, ptr inttoptr (i32 -1073741792 to ptr)
188+
br label %return
189+
return:
190+
%val = phi i32 [%0, %if.true], [%1, %if.false]
191+
ret i32 %val
192+
}
193+
194+
195+
; For addresses between [0, 2048), we can use ld/sd xN, address(zero), so don't
196+
; hoist.
197+
define void @test19(ptr %s, i32 %size) nounwind {
198+
; CHECK-LABEL: test19
199+
; CHECK: store i32 20, ptr inttoptr (i32 2044 to ptr)
200+
; CHECK: store i32 10, ptr inttoptr (i32 2044 to ptr)
201+
entry:
202+
%cond = icmp eq i32 %size, 0
203+
br i1 %cond, label %if.true, label %exit
204+
if.true:
205+
store i32 20, ptr inttoptr (i32 2044 to ptr)
206+
br label %exit
207+
exit:
208+
store i32 10, ptr inttoptr (i32 2044 to ptr)
209+
ret void
210+
}

0 commit comments

Comments
 (0)