
This patch canonicalizes getelementptr instructions with constant indices to use the `i8` source element type. This makes it easier for optimizations to recognize that two GEPs are identical, because they don't need to see past many different ways to express the same offset. This is a first step towards https://discourse.llvm.org/t/rfc-replacing-getelementptr-with-ptradd/68699. This is limited to constant GEPs only for now, as they have a clear canonical form, while we're not yet sure how exactly to deal with variable indices. The test llvm/test/Transforms/PhaseOrdering/switch_with_geps.ll gives two representative examples of the kind of optimization improvement we expect from this change. In the first test SimplifyCFG can now realize that all switch branches are actually the same. In the second test it can convert it into simple arithmetic. These are representative of common optimization failures we see in Rust. Fixes https://github.com/llvm/llvm-project/issues/69841.
56 lines
1.8 KiB
LLVM
56 lines
1.8 KiB
LLVM
; NOTE: Assertions have been autogenerated by utils/update_test_checks.py
|
|
; RUN: opt -O3 -S < %s | FileCheck %s
|
|
|
|
target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64"
|
|
target triple = "x86_64-apple-macosx10.6.7"
|
|
|
|
declare ptr @malloc(i64)
|
|
declare void @free(ptr)
|
|
|
|
; PR2338
|
|
define void @test1() nounwind ssp {
|
|
; CHECK-LABEL: @test1(
|
|
; CHECK-NEXT: ret void
|
|
;
|
|
%retval = alloca i32, align 4
|
|
%i = alloca ptr, align 8
|
|
%call = call ptr @malloc(i64 1)
|
|
store ptr %call, ptr %i, align 8
|
|
%tmp = load ptr, ptr %i, align 8
|
|
store i8 1, ptr %tmp
|
|
%tmp1 = load ptr, ptr %i, align 8
|
|
call void @free(ptr %tmp1)
|
|
ret void
|
|
|
|
}
|
|
|
|
; This function exposes a phase ordering problem when InstCombine is
|
|
; turning %add into a bitmask, making it difficult to spot a 0 return value.
|
|
;
|
|
; It it also important that %add is expressed as a multiple of %div so scalar
|
|
; evolution can recognize it.
|
|
define i32 @test2(i32 %a, ptr %p) nounwind uwtable ssp {
|
|
; CHECK-LABEL: @test2(
|
|
; CHECK-NEXT: entry:
|
|
; CHECK-NEXT: [[DIV1:%.*]] = lshr i32 [[A:%.*]], 2
|
|
; CHECK-NEXT: store i32 [[DIV1]], ptr [[P:%.*]], align 4
|
|
; CHECK-NEXT: [[ADD:%.*]] = shl nuw nsw i32 [[DIV1]], 1
|
|
; CHECK-NEXT: [[ARRAYIDX1:%.*]] = getelementptr inbounds i8, ptr [[P]], i64 4
|
|
; CHECK-NEXT: store i32 [[ADD]], ptr [[ARRAYIDX1]], align 4
|
|
; CHECK-NEXT: ret i32 0
|
|
;
|
|
entry:
|
|
%div = udiv i32 %a, 4
|
|
store i32 %div, ptr %p, align 4
|
|
%add = add i32 %div, %div
|
|
%arrayidx1 = getelementptr inbounds i32, ptr %p, i64 1
|
|
store i32 %add, ptr %arrayidx1, align 4
|
|
%arrayidx2 = getelementptr inbounds i32, ptr %p, i64 1
|
|
%0 = load i32, ptr %arrayidx2, align 4
|
|
%1 = load i32, ptr %p, align 4
|
|
%mul = mul i32 2, %1
|
|
%sub = sub i32 %0, %mul
|
|
ret i32 %sub
|
|
|
|
}
|