|  | 
|  | 1 | +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 5 | 
|  | 2 | +; RUN: opt -p globalopt -S %s | FileCheck %s | 
|  | 3 | + | 
|  | 4 | +@gvar0 = constant { <{ i64, i64, i64, [253 x i64] }> } { <{ i64, i64, i64, [253 x i64] }> <{ i64 -5, i64 1, i64 10, [253 x i64] zeroinitializer }> }, align 8 | 
|  | 5 | +@gvar1 = constant { <{ i64, i64, i64, [253 x i64] }> } { <{ i64, i64, i64, [253 x i64] }> <{ i64 0, i64 1, i64 5, [253 x i64] zeroinitializer }> }, align 8 | 
|  | 6 | +@gvar2 = global { <{ i64, i64, i64, [253 x i64] }> } { <{ i64, i64, i64, [253 x i64] }> <{ i64 0, i64 1, i64 2, [253 x i64] zeroinitializer }> }, align 8 | 
|  | 7 | +@gvar3 = constant [8 x i32] [i32 0, i32 1, i32 2, i32 0, i32 0, i32 100, i32 -6789, i32 8388608], align 16 | 
|  | 8 | +@gvar4 = constant [8 x i32] [i32 0, i32 1, i32 2, i32 0, i32 0, i32 100, i32 -6789, i32 8388608], align 16 | 
|  | 9 | +@gvar5 = constant [2 x [6 x i8]] [[6 x i8] c"\01a_\02-0", [6 x i8] c" \0E\FF\07\08\09"], align 1 | 
|  | 10 | + | 
|  | 11 | +define i64 @test_basic0(i64 %3) { | 
|  | 12 | +; CHECK-LABEL: define i64 @test_basic0( | 
|  | 13 | +; CHECK-SAME: i64 [[TMP0:%.*]]) local_unnamed_addr { | 
|  | 14 | +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [256 x i64], ptr @gvar0, i64 0, i64 [[TMP0]] | 
|  | 15 | +; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[PTR]], align 8, !range [[RNG0:![0-9]+]] | 
|  | 16 | +; CHECK-NEXT: ret i64 [[TMP2]] | 
|  | 17 | +; | 
|  | 18 | + %ptr = getelementptr inbounds [256 x i64], ptr @gvar0, i64 0, i64 %3 | 
|  | 19 | + %5 = load i64, ptr %ptr, align 8 | 
|  | 20 | + ret i64 %5 | 
|  | 21 | +} | 
|  | 22 | + | 
|  | 23 | +define i64 @test_basic1(i64 %3) { | 
|  | 24 | +; CHECK-LABEL: define i64 @test_basic1( | 
|  | 25 | +; CHECK-SAME: i64 [[TMP0:%.*]]) local_unnamed_addr { | 
|  | 26 | +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [32 x i64], ptr @gvar0, i64 0, i64 [[TMP0]] | 
|  | 27 | +; CHECK-NEXT: [[TMP2:%.*]] = load i64, ptr [[PTR]], align 8, !range [[RNG0]] | 
|  | 28 | +; CHECK-NEXT: ret i64 [[TMP2]] | 
|  | 29 | +; | 
|  | 30 | + %ptr = getelementptr inbounds [32 x i64], ptr @gvar0, i64 0, i64 %3 | 
|  | 31 | + %5 = load i64, ptr %ptr, align 8 | 
|  | 32 | + ret i64 %5 | 
|  | 33 | +} | 
|  | 34 | + | 
|  | 35 | +define i32 @test_different_type(i64 %3) { | 
|  | 36 | +; CHECK-LABEL: define i32 @test_different_type( | 
|  | 37 | +; CHECK-SAME: i64 [[TMP0:%.*]]) local_unnamed_addr { | 
|  | 38 | +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [512 x i32], ptr @gvar1, i64 0, i64 [[TMP0]] | 
|  | 39 | +; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[PTR]], align 8, !range [[RNG1:![0-9]+]] | 
|  | 40 | +; CHECK-NEXT: ret i32 [[TMP2]] | 
|  | 41 | +; | 
|  | 42 | + %ptr = getelementptr inbounds [512 x i32], ptr @gvar1, i64 0, i64 %3 | 
|  | 43 | + %5 = load i32, ptr %ptr, align 8 | 
|  | 44 | + ret i32 %5 | 
|  | 45 | +} | 
|  | 46 | + | 
|  | 47 | +define i32 @test_non_constant(i64 %3) { | 
|  | 48 | +; CHECK-LABEL: define i32 @test_non_constant( | 
|  | 49 | +; CHECK-SAME: i64 [[TMP0:%.*]]) local_unnamed_addr { | 
|  | 50 | +; CHECK-NEXT: [[PTR:%.*]] = getelementptr inbounds [512 x i32], ptr @gvar2, i64 0, i64 [[TMP0]] | 
|  | 51 | +; CHECK-NEXT: [[TMP2:%.*]] = load i32, ptr [[PTR]], align 8 | 
|  | 52 | +; CHECK-NEXT: ret i32 [[TMP2]] | 
|  | 53 | +; | 
|  | 54 | + %ptr = getelementptr inbounds [512 x i32], ptr @gvar2, i64 0, i64 %3 | 
|  | 55 | + %5 = load i32, ptr %ptr, align 8 | 
|  | 56 | + ret i32 %5 | 
|  | 57 | +} | 
|  | 58 | + | 
|  | 59 | +define i64 @test_other(i8 %first_idx) { | 
|  | 60 | +; CHECK-LABEL: define i64 @test_other( | 
|  | 61 | +; CHECK-SAME: i8 [[FIRST_IDX:%.*]]) local_unnamed_addr { | 
|  | 62 | +; CHECK-NEXT: [[ENTRY:.*:]] | 
|  | 63 | +; CHECK-NEXT: [[IDXPROM:%.*]] = zext i8 [[FIRST_IDX]] to i64 | 
|  | 64 | +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr @gvar3, i64 [[IDXPROM]] | 
|  | 65 | +; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8, !range [[RNG2:![0-9]+]] | 
|  | 66 | +; CHECK-NEXT: ret i64 [[TMP0]] | 
|  | 67 | +; | 
|  | 68 | +entry: | 
|  | 69 | + %idxprom = zext i8 %first_idx to i64 | 
|  | 70 | + %arrayidx = getelementptr inbounds i64, ptr @gvar3, i64 %idxprom | 
|  | 71 | + %0 = load i64, ptr %arrayidx, align 8 | 
|  | 72 | + ret i64 %0 | 
|  | 73 | +} | 
|  | 74 | + | 
|  | 75 | +; This could be supported but is rare and more complex for for now we dont process it. | 
|  | 76 | +define i64 @test_multiple_types0(i8 %first_idx) { | 
|  | 77 | +; CHECK-LABEL: define i64 @test_multiple_types0( | 
|  | 78 | +; CHECK-SAME: i8 [[FIRST_IDX:%.*]]) local_unnamed_addr { | 
|  | 79 | +; CHECK-NEXT: [[ENTRY:.*:]] | 
|  | 80 | +; CHECK-NEXT: [[IDXPROM:%.*]] = zext i8 [[FIRST_IDX]] to i64 | 
|  | 81 | +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i64, ptr @gvar4, i64 [[IDXPROM]] | 
|  | 82 | +; CHECK-NEXT: [[TMP0:%.*]] = load i64, ptr [[ARRAYIDX]], align 8 | 
|  | 83 | +; CHECK-NEXT: ret i64 [[TMP0]] | 
|  | 84 | +; | 
|  | 85 | +entry: | 
|  | 86 | + %idxprom = zext i8 %first_idx to i64 | 
|  | 87 | + %arrayidx = getelementptr inbounds i64, ptr @gvar4, i64 %idxprom | 
|  | 88 | + %0 = load i64, ptr %arrayidx, align 8 | 
|  | 89 | + ret i64 %0 | 
|  | 90 | +} | 
|  | 91 | + | 
|  | 92 | +define i32 @test_multiple_types1(i8 %first_idx) { | 
|  | 93 | +; CHECK-LABEL: define i32 @test_multiple_types1( | 
|  | 94 | +; CHECK-SAME: i8 [[FIRST_IDX:%.*]]) local_unnamed_addr { | 
|  | 95 | +; CHECK-NEXT: [[ENTRY:.*:]] | 
|  | 96 | +; CHECK-NEXT: [[IDXPROM:%.*]] = zext i8 [[FIRST_IDX]] to i64 | 
|  | 97 | +; CHECK-NEXT: [[ARRAYIDX:%.*]] = getelementptr inbounds i32, ptr @gvar4, i64 [[IDXPROM]] | 
|  | 98 | +; CHECK-NEXT: [[TMP0:%.*]] = load i32, ptr [[ARRAYIDX]], align 8 | 
|  | 99 | +; CHECK-NEXT: ret i32 [[TMP0]] | 
|  | 100 | +; | 
|  | 101 | +entry: | 
|  | 102 | + %idxprom = zext i8 %first_idx to i64 | 
|  | 103 | + %arrayidx = getelementptr inbounds i32, ptr @gvar4, i64 %idxprom | 
|  | 104 | + %0 = load i32, ptr %arrayidx, align 8 | 
|  | 105 | + ret i32 %0 | 
|  | 106 | +} | 
|  | 107 | + | 
|  | 108 | +; This could be supported also be supported, but for now it not. | 
|  | 109 | +define dso_local noundef signext i8 @multi_dimentional(i8 noundef zeroext %0, i8 noundef zeroext %1) local_unnamed_addr #0 { | 
|  | 110 | +; CHECK-LABEL: define dso_local noundef signext i8 @multi_dimentional( | 
|  | 111 | +; CHECK-SAME: i8 noundef zeroext [[TMP0:%.*]], i8 noundef zeroext [[TMP1:%.*]]) local_unnamed_addr { | 
|  | 112 | +; CHECK-NEXT: [[TMP3:%.*]] = zext i8 [[TMP0]] to i64 | 
|  | 113 | +; CHECK-NEXT: [[TMP4:%.*]] = zext i8 [[TMP1]] to i64 | 
|  | 114 | +; CHECK-NEXT: [[TMP5:%.*]] = getelementptr inbounds [2 x [6 x i8]], ptr @gvar5, i64 0, i64 [[TMP3]], i64 [[TMP4]] | 
|  | 115 | +; CHECK-NEXT: [[TMP6:%.*]] = load i8, ptr [[TMP5]], align 1 | 
|  | 116 | +; CHECK-NEXT: ret i8 [[TMP6]] | 
|  | 117 | +; | 
|  | 118 | + %3 = zext i8 %0 to i64 | 
|  | 119 | + %4 = zext i8 %1 to i64 | 
|  | 120 | + %5 = getelementptr inbounds [2 x [6 x i8]], ptr @gvar5, i64 0, i64 %3, i64 %4 | 
|  | 121 | + %6 = load i8, ptr %5, align 1 | 
|  | 122 | + ret i8 %6 | 
|  | 123 | +} | 
|  | 124 | + | 
|  | 125 | +;. | 
|  | 126 | +; CHECK: [[RNG0]] = !{i64 -5, i64 11} | 
|  | 127 | +; CHECK: [[RNG1]] = !{i32 0, i32 6} | 
|  | 128 | +; CHECK: [[RNG2]] = !{i64 2, i64 36028801313924476} | 
|  | 129 | +;. | 
0 commit comments