1; RUN: opt -consthoist -S < %s | FileCheck %s 2target triple = "thumbv6m-none-eabi" 3 4; Allocas in the entry block get handled (for free) by 5; prologue/epilogue. Elsewhere they're fair game though. 6define void @avoid_allocas() { 7; CHECK-LABEL: @avoid_allocas 8; CHECK: %addr1 = alloca i8, i32 1000 9; CHECK: %addr2 = alloca i8, i32 1020 10 11 %addr1 = alloca i8, i32 1000 12 %addr2 = alloca i8, i32 1020 13 br label %elsewhere 14 15elsewhere: 16; CHECK: [[BASE:%.*]] = bitcast i32 1000 to i32 17; CHECK: alloca i8, i32 [[BASE]] 18; CHECK: [[NEXT:%.*]] = add i32 [[BASE]], 20 19; CHECK: alloca i8, i32 [[NEXT]] 20 21 %addr3 = alloca i8, i32 1000 22 %addr4 = alloca i8, i32 1020 23 24 ret void 25} 26 27; The case values of switch instructions are required to be constants. 28define void @avoid_switch(i32 %in) { 29; CHECK-LABEL: @avoid_switch 30; CHECK: switch i32 %in, label %default [ 31; CHECK: i32 1000, label %bb1 32; CHECK: i32 1020, label %bb2 33; CHECK: ] 34 35 switch i32 %in, label %default 36 [ i32 1000, label %bb1 37 i32 1020, label %bb2 ] 38 39bb1: 40 ret void 41 42bb2: 43 ret void 44 45default: 46 ret void 47} 48 49; We don't want to convert constant divides because the benefit from converting 50; them to a mul in the backend is larget than constant materialization savings. 51define void @signed_const_division(i32 %in1, i32 %in2, i32* %addr) { 52; CHECK-LABEL: @signed_const_division 53; CHECK: %res1 = sdiv i32 %l1, 1000000000 54; CHECK: %res2 = srem i32 %l2, 1000000000 55entry: 56 br label %loop 57 58loop: 59 %l1 = phi i32 [%res1, %loop], [%in1, %entry] 60 %l2 = phi i32 [%res2, %loop], [%in2, %entry] 61 %res1 = sdiv i32 %l1, 1000000000 62 store volatile i32 %res1, i32* %addr 63 %res2 = srem i32 %l2, 1000000000 64 store volatile i32 %res2, i32* %addr 65 %again = icmp eq i32 %res1, %res2 66 br i1 %again, label %loop, label %end 67 68end: 69 ret void 70} 71 72define void @unsigned_const_division(i32 %in1, i32 %in2, i32* %addr) { 73; CHECK-LABEL: @unsigned_const_division 74; CHECK: %res1 = udiv i32 %l1, 1000000000 75; CHECK: %res2 = urem i32 %l2, 1000000000 76 77entry: 78 br label %loop 79 80loop: 81 %l1 = phi i32 [%res1, %loop], [%in1, %entry] 82 %l2 = phi i32 [%res2, %loop], [%in2, %entry] 83 %res1 = udiv i32 %l1, 1000000000 84 store volatile i32 %res1, i32* %addr 85 %res2 = urem i32 %l2, 1000000000 86 store volatile i32 %res2, i32* %addr 87 %again = icmp eq i32 %res1, %res2 88 br i1 %again, label %loop, label %end 89 90end: 91 ret void 92} 93 94;PR 28282: even when data type is larger than 64-bit, the bit width of the 95;constant operand could be smaller than 64-bit. In this case, there is no 96;benefit to hoist the constant. 97define i32 @struct_type_test(i96 %a0, i96 %a1) { 98;CHECK-LABEL: @struct_type_test 99entry: 100;CHECK-NOT: %const = bitcast i96 32 to i96 101;CHECK: lshr0 = lshr i96 %a0, 32 102 %lshr0 = lshr i96 %a0, 32 103 %cast0 = trunc i96 %lshr0 to i32 104;CHECK: lshr1 = lshr i96 %a1, 32 105 %lshr1 = lshr i96 %a1, 32 106 %cast1 = trunc i96 %lshr1 to i32 107 %ret = add i32 %cast0, %cast1 108 ret i32 %ret 109} 110 111@exception_type = external global i8 112 113; Constants in inline ASM should not be hoisted. 114define i32 @inline_asm_invoke() personality i8* null { 115;CHECK-LABEL: @inline_asm_invoke 116;CHECK-NOT: %const = 214672 117;CHECK: %X = invoke i32 asm "bswap $0", "=r,r"(i32 214672) 118 %X = invoke i32 asm "bswap $0", "=r,r"(i32 214672) 119 to label %L unwind label %lpad 120;CHECK: %Y = invoke i32 asm "bswap $0", "=r,r"(i32 214672) 121 %Y = invoke i32 asm "bswap $0", "=r,r"(i32 214672) 122 to label %L unwind label %lpad 123L: 124 ret i32 %X 125lpad: 126 %lp = landingpad i32 127 cleanup 128 catch i8* @exception_type 129 ret i32 1 130} 131 132define i32 @inline_asm_call() { 133;CHECK-LABEL: @inline_asm_call 134;CHECK-NOT: %const = 214672 135;CHECK: %X = call i32 asm "bswap $0", "=r,r"(i32 214672) 136 %X = call i32 asm "bswap $0", "=r,r"(i32 214672) 137;CHECK: %Y = call i32 asm "bswap $0", "=r,r"(i32 214672) 138 %Y = call i32 asm "bswap $0", "=r,r"(i32 214672) 139 ret i32 %X 140} 141