Files
clang-p2996/llvm/test/CodeGen/RISCV/loop-strength-reduce-loop-invar.ll
Craig Topper aaad507546 [RISCV] Return false from isOffsetFoldingLegal instead of reversing the fold in lowering.
When lowering GlobalAddressNodes, we were removing a non-zero offset and
creating a separate ADD.

It already comes out of SelectionDAGBuilder with a separate ADD. The
ADD was being removed by DAGCombiner.

This patch disables the DAG combine so we don't have to reverse it.
Test changes all look to be instruction order changes. Probably due
to different DAG node ordering.

Differential Revision: https://reviews.llvm.org/D126558
2022-05-27 11:05:18 -07:00

97 lines
2.9 KiB
LLVM

; NOTE: Assertions have been autogenerated by utils/update_llc_test_checks.py
; RUN: llc < %s -mtriple=riscv32 -verify-machineinstrs | FileCheck %s -check-prefixes=RV32
; RUN: llc < %s -mtriple=riscv64 -verify-machineinstrs | FileCheck %s -check-prefixes=RV64
; Test case:
; - `A[row]` is loop invariant and should be hoisted up to preheader
; FIXME: RV32 is working as expected, but RV64 doesn't
; The following LLVM IR simulates:
; int A[16][16];
; void test(int row, int N) {
; for (int i=0; i<N; ++I) {
; A[row][i+1] = 4;
; A[row][i+2] = 5;
; }
; }
; After LSR:
; int A[16][16];
; void test(int row, int N) {
; for (int *ptr = A[row][2]; N>0; N--) {
; *(ptr-1) = 4;
; *(ptr) = 5;
; ++ptr;
; }
; }
@A = internal global [16 x [16 x i32]] zeroinitializer, align 32 ; <[16 x [16 x i32]]*> [#uses=2]
define void @test(i32 signext %row, i32 signext %N.in) nounwind {
; RV32-LABEL: test:
; RV32: # %bb.0: # %entry
; RV32-NEXT: blez a1, .LBB0_3
; RV32-NEXT: # %bb.1: # %cond_true.preheader
; RV32-NEXT: slli a0, a0, 6
; RV32-NEXT: lui a2, %hi(A)
; RV32-NEXT: addi a2, a2, %lo(A)
; RV32-NEXT: add a0, a2, a0
; RV32-NEXT: addi a0, a0, 8
; RV32-NEXT: li a2, 4
; RV32-NEXT: li a3, 5
; RV32-NEXT: .LBB0_2: # %cond_true
; RV32-NEXT: # =>This Inner Loop Header: Depth=1
; RV32-NEXT: sw a2, -4(a0)
; RV32-NEXT: sw a3, 0(a0)
; RV32-NEXT: addi a1, a1, -1
; RV32-NEXT: addi a0, a0, 4
; RV32-NEXT: bnez a1, .LBB0_2
; RV32-NEXT: .LBB0_3: # %return
; RV32-NEXT: ret
;
; RV64-LABEL: test:
; RV64: # %bb.0: # %entry
; RV64-NEXT: blez a1, .LBB0_3
; RV64-NEXT: # %bb.1: # %cond_true.preheader
; RV64-NEXT: li a4, 0
; RV64-NEXT: slli a0, a0, 6
; RV64-NEXT: lui a2, %hi(A)
; RV64-NEXT: addi a2, a2, %lo(A)
; RV64-NEXT: add a0, a2, a0
; RV64-NEXT: li a2, 4
; RV64-NEXT: li a3, 5
; RV64-NEXT: .LBB0_2: # %cond_true
; RV64-NEXT: # =>This Inner Loop Header: Depth=1
; RV64-NEXT: addiw a5, a4, 1
; RV64-NEXT: slli a6, a5, 2
; RV64-NEXT: add a6, a0, a6
; RV64-NEXT: sw a2, 0(a6)
; RV64-NEXT: addiw a4, a4, 2
; RV64-NEXT: slli a4, a4, 2
; RV64-NEXT: add a4, a0, a4
; RV64-NEXT: sw a3, 0(a4)
; RV64-NEXT: mv a4, a5
; RV64-NEXT: bne a5, a1, .LBB0_2
; RV64-NEXT: .LBB0_3: # %return
; RV64-NEXT: ret
entry:
%N = bitcast i32 %N.in to i32
%tmp5 = icmp sgt i32 %N.in, 0
br i1 %tmp5, label %cond_true, label %return
cond_true:
%indvar = phi i32 [ 0, %entry ], [ %indvar.next, %cond_true ]
%tmp2 = add i32 %indvar, 1
%tmp = getelementptr [16 x [16 x i32]], [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 %tmp2
store i32 4, i32* %tmp
%tmp5.upgrd.1 = add i32 %indvar, 2
%tmp7 = getelementptr [16 x [16 x i32]], [16 x [16 x i32]]* @A, i32 0, i32 %row, i32 %tmp5.upgrd.1
store i32 5, i32* %tmp7
%indvar.next = add i32 %indvar, 1
%exitcond = icmp eq i32 %indvar.next, %N
br i1 %exitcond, label %return, label %cond_true
return:
ret void
}