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