1; RUN: opt -consthoist -S -o - %s | FileCheck %s 2target datalayout = "e-m:e-p:32:32-i64:64-v128:64:128-a:0:32-n32-S64" 3target triple = "thumbv6m-none--musleabi" 4 5; Check that for i8 type, the maximum legal offset is 31. 6; Also check that an constant used as value to be stored rather than 7; pointer in a store instruction is hoisted. 8; CHECK: foo_i8 9; CHECK-DAG: %[[C1:const[0-9]?]] = bitcast i32 805874720 to i32 10; CHECK-DAG: %[[C2:const[0-9]?]] = bitcast i32 805874688 to i32 11; CHECK-DAG: %[[C3:const[0-9]?]] = bitcast i32 805873720 to i32 12; CHECK-DAG: %[[C4:const[0-9]?]] = bitcast i32 805873688 to i32 13; CHECK: %0 = inttoptr i32 %[[C2]] to i8* 14; CHECK-NEXT: %1 = load volatile i8, i8* %0 15; CHECK-NEXT: %[[M1:const_mat[0-9]?]] = add i32 %[[C2]], 4 16; CHECK-NEXT: %2 = inttoptr i32 %[[M1]] to i8* 17; CHECK-NEXT: %3 = load volatile i8, i8* %2 18; CHECK-NEXT: %[[M2:const_mat[0-9]?]] = add i32 %[[C2]], 31 19; CHECK-NEXT: %4 = inttoptr i32 %[[M2]] to i8* 20; CHECK-NEXT: %5 = load volatile i8, i8* %4 21; CHECK-NEXT: %6 = inttoptr i32 %[[C1]] to i8* 22; CHECK-NEXT: %7 = load volatile i8, i8* %6 23; CHECK-NEXT: %[[M3:const_mat[0-9]?]] = add i32 %[[C1]], 7 24; CHECK-NEXT: %8 = inttoptr i32 %[[M3]] to i8* 25; CHECK-NEXT: %9 = load volatile i8, i8* %8 26; CHECK-NEXT: %10 = inttoptr i32 %[[C4]] to i8* 27; CHECK-NEXT: store i8 %9, i8* %10 28; CHECK-NEXT: %[[M4:const_mat[0-9]?]] = add i32 %[[C4]], 31 29; CHECK-NEXT: %11 = inttoptr i32 %[[M4]] to i8* 30; CHECK-NEXT: store i8 %7, i8* %11 31; CHECK-NEXT: %12 = inttoptr i32 %[[C3]] to i8* 32; CHECK-NEXT: store i8 %5, i8* %12 33; CHECK-NEXT: %[[M5:const_mat[0-9]?]] = add i32 %[[C3]], 7 34; CHECK-NEXT: %13 = inttoptr i32 %[[M5]] to i8* 35; CHECK-NEXT: store i8 %3, i8* %13 36; CHECK-NEXT: %[[M6:const_mat[0-9]?]] = add i32 %[[C1]], 80 37; CHECK-NEXT: %14 = inttoptr i32 %[[M6]] to i8* 38; CHECK-NEXT: store i8* %14, i8** @goo 39 40@goo = global i8* undef 41 42define void @foo_i8() { 43entry: 44 %0 = load volatile i8, i8* inttoptr (i32 805874688 to i8*) 45 %1 = load volatile i8, i8* inttoptr (i32 805874692 to i8*) 46 %2 = load volatile i8, i8* inttoptr (i32 805874719 to i8*) 47 %3 = load volatile i8, i8* inttoptr (i32 805874720 to i8*) 48 %4 = load volatile i8, i8* inttoptr (i32 805874727 to i8*) 49 store i8 %4, i8* inttoptr(i32 805873688 to i8*) 50 store i8 %3, i8* inttoptr(i32 805873719 to i8*) 51 store i8 %2, i8* inttoptr(i32 805873720 to i8*) 52 store i8 %1, i8* inttoptr(i32 805873727 to i8*) 53 store i8* inttoptr(i32 805874800 to i8*), i8** @goo 54 ret void 55} 56 57; Check that for i16 type, the maximum legal offset is 62. 58; CHECK: foo_i16 59; CHECK-DAG: %[[C1:const[0-9]?]] = bitcast i32 805874752 to i32 60; CHECK-DAG: %[[C2:const[0-9]?]] = bitcast i32 805874688 to i32 61; CHECK: %0 = inttoptr i32 %[[C2]] to i16* 62; CHECK-NEXT: %1 = load volatile i16, i16* %0, align 2 63; CHECK-NEXT: %[[M1:const_mat[0-9]?]] = add i32 %[[C2]], 4 64; CHECK-NEXT: %2 = inttoptr i32 %[[M1]] to i16* 65; CHECK-NEXT: %3 = load volatile i16, i16* %2, align 2 66; CHECK-NEXT: %[[M2:const_mat[0-9]?]] = add i32 %[[C2]], 32 67; CHECK-NEXT: %4 = inttoptr i32 %[[M2]] to i16* 68; CHECK-NEXT: %5 = load volatile i16, i16* %4, align 2 69; CHECK-NEXT: %[[M3:const_mat[0-9]?]] = add i32 %[[C2]], 62 70; CHECK-NEXT: %6 = inttoptr i32 %[[M3]] to i16* 71; CHECK-NEXT: %7 = load volatile i16, i16* %6, align 2 72; CHECK-NEXT: %8 = inttoptr i32 %[[C1]] to i16* 73; CHECK-NEXT: %9 = load volatile i16, i16* %8, align 2 74; CHECK-NEXT: %[[M4:const_mat[0-9]?]] = add i32 %[[C1]], 22 75; CHECK-NEXT: %10 = inttoptr i32 %[[M4]] to i16* 76; CHECK-NEXT: %11 = load volatile i16, i16* %10, align 2 77 78define void @foo_i16() { 79entry: 80 %0 = load volatile i16, i16* inttoptr (i32 805874688 to i16*), align 2 81 %1 = load volatile i16, i16* inttoptr (i32 805874692 to i16*), align 2 82 %2 = load volatile i16, i16* inttoptr (i32 805874720 to i16*), align 2 83 %3 = load volatile i16, i16* inttoptr (i32 805874750 to i16*), align 2 84 %4 = load volatile i16, i16* inttoptr (i32 805874752 to i16*), align 2 85 %5 = load volatile i16, i16* inttoptr (i32 805874774 to i16*), align 2 86 ret void 87} 88 89; Check that for i32 type, the maximum legal offset is 124. 90; CHECK: foo_i32 91; CHECK-DAG: %[[C1:const[0-9]?]] = bitcast i32 805874816 to i32 92; CHECK-DAG: %[[C2:const[0-9]?]] = bitcast i32 805874688 to i32 93; CHECK: %0 = inttoptr i32 %[[C2]] to i32* 94; CHECK-NEXT: %1 = load volatile i32, i32* %0, align 4 95; CHECK-NEXT: %[[M1:const_mat[0-9]?]] = add i32 %[[C2]], 4 96; CHECK-NEXT: %2 = inttoptr i32 %[[M1]] to i32* 97; CHECK-NEXT: %3 = load volatile i32, i32* %2, align 4 98; CHECK-NEXT: %[[M2:const_mat[0-9]?]] = add i32 %[[C2]], 124 99; CHECK-NEXT: %4 = inttoptr i32 %[[M2]] to i32* 100; CHECK-NEXT: %5 = load volatile i32, i32* %4, align 4 101; CHECK-NEXT: %6 = inttoptr i32 %[[C1]] to i32* 102; CHECK-NEXT: %7 = load volatile i32, i32* %6, align 4 103; CHECK-NEXT: %[[M3:const_mat[0-9]?]] = add i32 %[[C1]], 8 104; CHECK-NEXT: %8 = inttoptr i32 %[[M3]] to i32* 105; CHECK-NEXT: %9 = load volatile i32, i32* %8, align 4 106; CHECK-NEXT: %[[M4:const_mat[0-9]?]] = add i32 %[[C1]], 12 107; CHECK-NEXT: %10 = inttoptr i32 %[[M4]] to i32* 108; CHECK-NEXT: %11 = load volatile i32, i32* %10, align 4 109 110define void @foo_i32() { 111entry: 112 %0 = load volatile i32, i32* inttoptr (i32 805874688 to i32*), align 4 113 %1 = load volatile i32, i32* inttoptr (i32 805874692 to i32*), align 4 114 %2 = load volatile i32, i32* inttoptr (i32 805874812 to i32*), align 4 115 %3 = load volatile i32, i32* inttoptr (i32 805874816 to i32*), align 4 116 %4 = load volatile i32, i32* inttoptr (i32 805874824 to i32*), align 4 117 %5 = load volatile i32, i32* inttoptr (i32 805874828 to i32*), align 4 118 ret void 119} 120 121