1; RUN: opt < %s -instcombine -S | FileCheck %s
2target 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"
3target triple = "x86_64-pc-win32"
4
5declare void @use(i32) readonly
6
7; We prefer to canonicalize the machine width gep indices early
8define void @test(i32* %p, i32 %index) {
9; CHECK-LABEL: @test
10; CHECK-NEXT: %1 = sext i32 %index to i64
11; CHECK-NEXT: %addr = getelementptr i32, i32* %p, i64 %1
12  %addr = getelementptr i32, i32* %p, i32 %index
13  %val = load i32, i32* %addr
14  call void @use(i32 %val)
15  ret void
16}
17; If they've already been canonicalized via zext, that's fine
18define void @test2(i32* %p, i32 %index) {
19; CHECK-LABEL: @test2
20; CHECK-NEXT: %i = zext i32 %index to i64
21; CHECK-NEXT: %addr = getelementptr i32, i32* %p, i64 %i
22  %i = zext i32 %index to i64
23  %addr = getelementptr i32, i32* %p, i64 %i
24  %val = load i32, i32* %addr
25  call void @use(i32 %val)
26  ret void
27}
28; If we can use a zext, we prefer that.  This requires
29; knowing that the index is positive.
30define void @test3(i32* %p, i32 %index) {
31; CHECK-LABEL: @test3
32; CHECK:   zext
33; CHECK-NOT: sext
34  %addr_begin = getelementptr i32, i32* %p, i64 40
35  %addr_fixed = getelementptr i32, i32* %addr_begin, i64 48
36  %val_fixed = load i32, i32* %addr_fixed, !range !0
37  %addr = getelementptr i32, i32* %addr_begin, i32 %val_fixed
38  %val = load i32, i32* %addr
39  call void @use(i32 %val)
40  ret void
41}
42; Replace sext with zext where possible
43define void @test4(i32* %p, i32 %index) {
44; CHECK-LABEL: @test4
45; CHECK:   zext
46; CHECK-NOT: sext
47  %addr_begin = getelementptr i32, i32* %p, i64 40
48  %addr_fixed = getelementptr i32, i32* %addr_begin, i64 48
49  %val_fixed = load i32, i32* %addr_fixed, !range !0
50  %i = sext i32 %val_fixed to i64
51  %addr = getelementptr i32, i32* %addr_begin, i64 %i
52  %val = load i32, i32* %addr
53  call void @use(i32 %val)
54  ret void
55}
56
57;;  !range !0
58!0 = !{i32 0, i32 2147483647}
59
60
61
62