; RUN: opt < %s -nacl-promote-ints -S | FileCheck %s declare void @consume_i16(i16 %a) ; CHECK: @sext_to_illegal ; CHECK-NEXT: %a40 = sext i32 %a to i64 ; (0xFFFFFFFFFF) define void @sext_to_illegal(i32 %a) { %a40 = sext i32 %a to i40 ret void } ; CHECK; @sext_from_illegal define void @sext_from_illegal(i8 %a) { ; CHECK: call void @consume_i16(i16 -2) %c12 = sext i12 -2 to i16 call void @consume_i16(i16 %c12) ; CHECK: %a12 = sext i8 %a to i16 %a12 = sext i8 %a to i12 ; CHECK: %a12.getsign = shl i16 %a12, 4 ; CHECK-NEXT: %a16 = ashr i16 %a12.getsign, 4 %a16 = sext i12 %a12 to i16 ; CHECK: %a12.getsign1 = shl i16 %a12, 4 ; CHECK-NEXT: %a14 = ashr i16 %a12.getsign1, 4 ; (0x3FFF) %a14 = sext i12 %a12 to i14 ; CHECK-NEXT: %a12.getsign2 = shl i16 %a12, 4 ; CHECK-NEXT: %a12.signed = ashr i16 %a12.getsign2, 4 ; CHECK-NEXT: %a24 = sext i16 %a12.signed to i32 ; (0xFFFFFF) %a24 = sext i12 %a12 to i24 %a37 = zext i8 %a to i37 ; CHECK: %a37.getsign = shl i64 %a37, 27 ; CHECK-NEXT: %a64 = ashr i64 %a37.getsign, 27 %a64 = sext i37 %a37 to i64 ret void } ; CHECK: @zext_to_illegal define void @zext_to_illegal(i32 %a) { ; CHECK: zext i32 %a to i64 ; CHECK-NOT: and %a40 = zext i32 %a to i40 ret void } ; CHECK: @zext_from_illegal define void @zext_from_illegal(i8 %a) { ; get some illegal values to start with %a24 = zext i8 %a to i24 %a40 = zext i8 %a to i40 %a18 = zext i8 %a to i18 ; CHECK: %a32 = and i32 %a24, 16777215 ; (0xFFFFFF) %a32 = zext i24 %a24 to i32 ; CHECK: %b24 = and i32 %a18, 262143 ; (0x3FFFF) %b24 = zext i18 %a18 to i24 ; CHECK: %a24.clear = and i32 %a24, 16777215 ; CHECK: %b40 = zext i32 %a24.clear to i64 %b40 = zext i24 %a24 to i40 ; CHECK: call void @consume_i16(i16 4094) %c16 = zext i12 -2 to i16 call void @consume_i16(i16 %c16) ; CHECK: call void @consume_i16(i16 4094) %c14 = zext i12 -2 to i14 %c16.2 = zext i14 %c14 to i16 call void @consume_i16(i16 %c16.2) ret void } ; CHECK: @trunc_from_illegal define void @trunc_from_illegal(i8 %a) { %a24 = zext i8 %a to i24 ; CHECK: %a16 = trunc i32 %a24 to i16 %a16 = trunc i24 %a24 to i16 ret void } ; CHECK: @trunc_to_illegal define void @trunc_to_illegal(i8 %a8) { %a = zext i8 %a8 to i32 ; CHECK-NOT: trunc i32 %a ; CHECK-NOT: and %a24 = trunc i32 %a to i24 ; CHECK: %a12 = trunc i32 %a24 to i16 ; CHECK-NOT: and %a12 = trunc i24 %a24 to i12 ret void } ; CHECK: @icmpsigned define void @icmpsigned(i32 %a) { %shl = trunc i32 %a to i24 ; CHECK: %shl.getsign = shl i32 %shl, 8 ; CHECK-NEXT: %shl.signed = ashr i32 %shl.getsign, 8 ; CHECK-NEXT: %cmp = icmp slt i32 %shl.signed, -2 %cmp = icmp slt i24 %shl, -2 ret void } %struct.ints = type { i32, i32 } ; CHECK: @bc1 ; CHECK: bc1 = bitcast i32* %a to i64* ; CHECK-NEXT: bc2 = bitcast i64* %bc1 to i32* ; CHECK-NEXT: bc3 = bitcast %struct.ints* null to i64* ; CHECK-NEXT: bc4 = bitcast i64* %bc1 to %struct.ints* define i32* @bc1(i32* %a) { %bc1 = bitcast i32* %a to i40* %bc2 = bitcast i40* %bc1 to i32* %bc3 = bitcast %struct.ints* null to i40* %bc4 = bitcast i40* %bc1 to %struct.ints* ret i32* %bc2 } ; CHECK: zext i32 %a to i64 ; CHECK: and i64 %a40, 255 define void @and1(i32 %a) { %a40 = zext i32 %a to i40 %and = and i40 %a40, 255 ret void } ; CHECK: @andi3 define void @andi3(i8 %a) { %a3 = trunc i8 %a to i3 ; CHECK: and i8 %a3, 2 %and = and i3 %a3, 2 ret void } ; CHECK: @ori7 define void @ori7(i8 %a, i8 %b) { %a7 = trunc i8 %a to i7 %b7 = trunc i8 %b to i7 ; CHECK: %or = or i8 %a7, %b7 %or = or i7 %a7, %b7 ret void } ; CHECK: @add1 define void @add1(i16 %a) { ; CHECK-NEXT: %a24 = sext i16 %a to i32 %a24 = sext i16 %a to i24 ; CHECK-NEXT: %sum = add i32 %a24, 16777214 %sum = add i24 %a24, -2 ; CHECK-NEXT: %sumnsw = add nsw i32 %a24, 16777214 %sumnsw = add nsw i24 %a24, -2 ; CHECK-NEXT: %sumnuw = add nuw i32 %a24, 16777214 %sumnuw = add nuw i24 %a24, -2 ; CHECK-NEXT: %sumnw = add nuw nsw i32 %a24, 16777214 %sumnw = add nuw nsw i24 %a24, -2 ret void } ; CHECK: @mul1 define void @mul1(i32 %a, i32 %b) { ; CHECK-NEXT: %a33 = sext i32 %a to i64 %a33 = sext i32 %a to i33 ; CHECK-NEXT: %b33 = sext i32 %b to i64 %b33 = sext i32 %b to i33 ; CHECK-NEXT: %product = mul i64 %a33, %b33 %product = mul i33 %a33, %b33 ; CHECK-NEXT: %prodnw = mul nuw nsw i64 %a33, %b33 %prodnw = mul nuw nsw i33 %a33, %b33 ret void } ; CHECK: @shl1 define void @shl1(i16 %a) { %a24 = zext i16 %a to i24 ; CHECK: %ashl = shl i32 %a24, 5 %ashl = shl i24 %a24, 5 ; CHECK-NEXT: %ashl2 = shl i32 %a24, 1 %ashl2 = shl i24 %a24, 4278190081 ;0xFF000001 %b24 = zext i16 %a to i24 ; CHECK: %b24.clear = and i32 %b24, 16777215 ; CHECK-NEXT: %bshl = shl i32 %a24, %b24.clear %bshl = shl i24 %a24, %b24 ret void } ; CHECK: @shlnuw define void @shlnuw(i16 %a) { %a12 = trunc i16 %a to i12 ; CHECK: %ashl = shl nuw i16 %a12, 5 %ashl = shl nuw i12 %a12, 5 ret void } ; CHECK: @lshr1 define void @lshr1(i16 %a) { %a24 = zext i16 %a to i24 ; CHECK: %a24.clear = and i32 %a24, 16777215 ; CHECK-NEXT: %b = lshr i32 %a24.clear, 20 %b = lshr i24 %a24, 20 ; CHECK-NEXT: %a24.clear1 = and i32 %a24, 16777215 ; CHECK-NEXT: %c = lshr i32 %a24.clear1, 5 %c = lshr i24 %a24, 5 %b24 = zext i16 %a to i24 %d = lshr i24 %a24, %b24 ; CHECK: %a24.clear2 = and i32 %a24, 16777215 ; CHECK-NEXT: %b24.clear = and i32 %b24, 16777215 ; CHECK-NEXT: %d = lshr i32 %a24.clear2, %b24.clear ret void } ; CHECK: @ashr1 define void @ashr1(i16 %a) { %a24 = sext i16 %a to i24 ; CHECK: %a24.getsign = shl i32 %a24, 8 ; CHECK-NEXT: %b24 = ashr i32 %a24.getsign, 19 %b24 = ashr i24 %a24, 11 ; CHECK-NEXT: %a24.getsign1 = shl i32 %a24, 8 ; CHECK-NEXT: %b24.clear = and i32 %b24, 16777215 ; CHECK-NEXT: %a24.shamt = add i32 %b24.clear, 8 ; CHECK-NEXT: %c = ashr i32 %a24.getsign1, %a24.shamt %c = ashr i24 %a24, %b24 ret void } ; CHECK: @udiv1 define void @udiv1(i32 %a, i32 %b) { ; CHECK-NEXT: %a33 = zext i32 %a to i64 %a33 = zext i32 %a to i33 ; CHECK-NEXT: %b33 = zext i32 %b to i64 %b33 = zext i32 %b to i33 ; CHECK-NEXT: %a33.clear = and i64 %a33, 8589934591 ; CHECK-NEXT: %b33.clear = and i64 %b33, 8589934591 ; CHECK-NEXT: %result = udiv i64 %a33.clear, %b33.clear %result = udiv i33 %a33, %b33 ret void } ; CHECK: @sdiv1 define void @sdiv1(i32 %a, i32 %b) { ; CHECK-NEXT: %a33 = sext i32 %a to i64 %a33 = sext i32 %a to i33 ; CHECK-NEXT: %b33 = sext i32 %b to i64 ; CHECK-NEXT: %a33.getsign = shl i64 %a33, 31 ; CHECK-NEXT: %a33.signed = ashr i64 %a33.getsign, 31 ; CHECK-NEXT: %b33.getsign = shl i64 %b33, 31 ; CHECK-NEXT: %b33.signed = ashr i64 %b33.getsign, 31 %b33 = sext i32 %b to i33 ; CHECK-NEXT: %result = sdiv i64 %a33.signed, %b33.signed %result = sdiv i33 %a33, %b33 ret void } ; CHECK: @urem1 define void @urem1(i32 %a, i32 %b) { ; CHECK-NEXT: %a33 = zext i32 %a to i64 %a33 = zext i32 %a to i33 ; CHECK-NEXT: %b33 = zext i32 %b to i64 ; CHECK-NEXT: %a33.clear = and i64 %a33, 8589934591 ; CHECK-NEXT: %b33.clear = and i64 %b33, 8589934591 %b33 = zext i32 %b to i33 ; CHECK-NEXT: %result = urem i64 %a33.clear, %b33.clear %result = urem i33 %a33, %b33 ret void } ; CHECK: @srem1 define void @srem1(i32 %a, i32 %b) { ; CHECK-NEXT: %a33 = sext i32 %a to i64 %a33 = sext i32 %a to i33 ; CHECK-NEXT: %b33 = sext i32 %b to i64 ; CHECK-NEXT: %a33.getsign = shl i64 %a33, 31 ; CHECK-NEXT: %a33.signed = ashr i64 %a33.getsign, 31 ; CHECK-NEXT: %b33.getsign = shl i64 %b33, 31 ; CHECK-NEXT: %b33.signed = ashr i64 %b33.getsign, 31 %b33 = sext i32 %b to i33 ; CHECK-NEXT: %result = srem i64 %a33.signed, %b33.signed %result = srem i33 %a33, %b33 ret void } ; CHECK: @phi_icmp define void @phi_icmp(i32 %a) { entry: br label %loop loop: ; CHECK: %phi40 = phi i64 [ 1099511627774, %entry ], [ %phi40, %loop ] %phi40 = phi i40 [ -2, %entry ], [ %phi40, %loop ] ; CHECK-NEXT: %phi40.clear = and i64 %phi40, 1099511627775 ; CHECK-NEXT: %b = icmp eq i64 %phi40.clear, 1099511627775 %b = icmp eq i40 %phi40, -1 ; CHECK-NEXT: br i1 %b, label %loop, label %end br i1 %b, label %loop, label %end end: ret void } ; CHECK: @icmp_ult define void @icmp_ult(i32 %a) { %a40 = zext i32 %a to i40 ; CHECK: %a40.clear = and i64 %a40, 1099511627775 ; CHECK-NEXT: %b = icmp ult i64 %a40.clear, 1099511627774 %b = icmp ult i40 %a40, -2 ; CHECK: %a40.clear1 = and i64 %a40, 1099511627775 ; CHECK-NEXT: %b40.clear = and i64 %b40, 1099511627775 ; CHECK-NEXT: %c = icmp ult i64 %a40.clear1, %b40.clear %b40 = zext i32 %a to i40 %c = icmp ult i40 %a40, %b40 ret void } ; CHECK: @select1 define void @select1(i32 %a) { %a40 = zext i32 %a to i40 ; CHECK: %s40 = select i1 true, i64 %a40, i64 1099511627775 %s40 = select i1 true, i40 %a40, i40 -1 ret void } ; CHECK: @alloca40 ; CHECK: %a = alloca i64, align 8 define void @alloca40() { %a = alloca i40, align 8 %b = bitcast i40* %a to i8* %c = load i8* %b ret void } ; CHECK: @load24 ; CHECK: %bc.loty = bitcast i32* %bc to i16* ; CHECK-NEXT: %load.lo = load i16* %bc.loty ; CHECK-NEXT: %load.lo.ext = zext i16 %load.lo to i32 ; CHECK-NEXT: %bc.hi = getelementptr i16* %bc.loty, i32 1 ; CHECK-NEXT: %bc.hity = bitcast i16* %bc.hi to i8* ; CHECK-NEXT: %load.hi = load i8* %bc.hity ; CHECK-NEXT: %load.hi.ext = zext i8 %load.hi to i32 ; CHECK-NEXT: %load.hi.ext.sh = shl i32 %load.hi.ext, 16 ; CHECK-NEXT: %load = or i32 %load.lo.ext, %load.hi.ext.sh define void @load24(i8* %a) { %bc = bitcast i8* %a to i24* %load = load i24* %bc, align 8 ret void } ; CHECK: @load48 ; CHECK: %bc.loty = bitcast i64* %bc to i32* ; CHECK-NEXT: %load.lo = load i32* %bc.loty ; CHECK-NEXT: %load.lo.ext = zext i32 %load.lo to i64 ; CHECK-NEXT: %bc.hi = getelementptr i32* %bc.loty, i32 1 ; CHECK-NEXT: %bc.hity = bitcast i32* %bc.hi to i16* ; CHECK-NEXT: %load.hi = load i16* %bc.hity ; CHECK-NEXT: %load.hi.ext = zext i16 %load.hi to i64 ; CHECK-NEXT: %load.hi.ext.sh = shl i64 %load.hi.ext, 32 ; CHECK-NEXT: %load = or i64 %load.lo.ext, %load.hi.ext.sh define void @load48(i32* %a) { %bc = bitcast i32* %a to i48* %load = load i48* %bc, align 8 ret void } ; CHECK: %bc = bitcast i32* %a to i64* ; CHECK-NEXT: %bc.loty = bitcast i64* %bc to i32* ; CHECK-NEXT: %load.lo = load i32* %bc.loty ; CHECK-NEXT: %load.lo.ext = zext i32 %load.lo to i64 ; CHECK-NEXT: %bc.hi = getelementptr i32* %bc.loty, i32 1 ; CHECK-NEXT: %bc.hity.loty = bitcast i32* %bc.hi to i16* ; CHECK-NEXT: %load.hi.lo = load i16* %bc.hity.loty ; CHECK-NEXT: %load.hi.lo.ext = zext i16 %load.hi.lo to i32 ; CHECK-NEXT: %bc.hity.hi = getelementptr i16* %bc.hity.loty, i32 1 ; CHECK-NEXT: %bc.hity.hity = bitcast i16* %bc.hity.hi to i8* ; CHECK-NEXT: %load.hi.hi = load i8* %bc.hity.hity ; CHECK-NEXT: %load.hi.hi.ext = zext i8 %load.hi.hi to i32 ; CHECK-NEXT: %load.hi.hi.ext.sh = shl i32 %load.hi.hi.ext, 16 ; CHECK-NEXT: %load.hi = or i32 %load.hi.lo.ext, %load.hi.hi.ext.sh ; CHECK-NEXT: %load.hi.ext = zext i32 %load.hi to i64 ; CHECK-NEXT: %load.hi.ext.sh = shl i64 %load.hi.ext, 32 ; CHECK-NEXT: %load = or i64 %load.lo.ext, %load.hi.ext.sh define void @load56(i32* %a) { %bc = bitcast i32* %a to i56* %load = load i56* %bc ret void } ; CHECK: @store24 ; CHECK: %b24 = zext i8 %b to i32 ; CHECK-NEXT: %bc.loty = bitcast i32* %bc to i16* ; CHECK-NEXT: %b24.lo = trunc i32 %b24 to i16 ; CHECK-NEXT: store i16 %b24.lo, i16* %bc.loty ; CHECK-NEXT: %b24.hi.sh = lshr i32 %b24, 16 ; CHECK-NEXT: %bc.hi = getelementptr i16* %bc.loty, i32 1 ; CHECK-NEXT: %b24.hi = trunc i32 %b24.hi.sh to i8 ; CHECK-NEXT: %bc.hity = bitcast i16* %bc.hi to i8* ; CHECK-NEXT: store i8 %b24.hi, i8* %bc.hity define void @store24(i8* %a, i8 %b) { %bc = bitcast i8* %a to i24* %b24 = zext i8 %b to i24 store i24 %b24, i24* %bc ret void } ; CHECK: @store56 ; CHECK: %b56 = zext i8 %b to i64 ; CHECK-NEXT: %bc.loty = bitcast i64* %bc to i32* ; CHECK-NEXT: %b56.lo = trunc i64 %b56 to i32 ; CHECK-NEXT: store i32 %b56.lo, i32* %bc.loty ; CHECK-NEXT: %b56.hi.sh = lshr i64 %b56, 32 ; CHECK-NEXT: %bc.hi = getelementptr i32* %bc.loty, i32 1 ; CHECK-NEXT: %bc.hity.loty = bitcast i32* %bc.hi to i16* ; CHECK-NEXT: %b56.hi.sh.lo = trunc i64 %b56.hi.sh to i16 ; CHECK-NEXT: store i16 %b56.hi.sh.lo, i16* %bc.hity.loty ; CHECK-NEXT: %b56.hi.sh.hi.sh = lshr i64 %b56.hi.sh, 16 ; CHECK-NEXT: %bc.hity.hi = getelementptr i16* %bc.hity.loty, i32 1 ; CHECK-NEXT: %b56.hi.sh.hi = trunc i64 %b56.hi.sh.hi.sh to i8 ; CHECK-NEXT: %bc.hity.hity = bitcast i16* %bc.hity.hi to i8* ; CHECK-NEXT: store i8 %b56.hi.sh.hi, i8* %bc.hity.hity define void @store56(i8* %a, i8 %b) { %bc = bitcast i8* %a to i56* %b56 = zext i8 %b to i56 store i56 %b56, i56* %bc ret void } ; CHECK: @undefoperand ; CHECK-NEXT: %a40 = zext i32 %a to i64 ; CHECK-NEXT: %au = and i64 %a40, undef define void @undefoperand(i32 %a) { %a40 = zext i32 %a to i40 %au = and i40 %a40, undef ret void } ; CHECK: @switch ; CHECK-NEXT: %a24 = zext i16 %a to i32 ; CHECK-NEXT: %a24.clear = and i32 %a24, 16777215 ; CHECK-NEXT: switch i32 %a24.clear, label %end [ ; CHECK-NEXT: i32 0, label %if1 ; CHECK-NEXT: i32 1, label %if2 define void @switch(i16 %a) { %a24 = zext i16 %a to i24 switch i24 %a24, label %end [ i24 0, label %if1 i24 1, label %if2 ] if1: ret void if2: ret void end: ret void } ; CHECK: @bigger_integers ; CHECK-NEXT: %q = bitcast i8* %p to i128* ; CHECK-NEXT: %q.loty = bitcast i128* %q to i64* ; CHECK-NEXT: %x.lo = load i64* %q.loty ; CHECK-NEXT: %x.lo.ext = zext i64 %x.lo to i128 ; CHECK-NEXT: %q.hi = getelementptr i64* %q.loty, i32 1 ; CHECK-NEXT: %q.hity.loty = bitcast i64* %q.hi to i32* ; CHECK-NEXT: %x.hi.lo = load i32* %q.hity.loty ; CHECK-NEXT: %x.hi.lo.ext = zext i32 %x.hi.lo to i64 ; CHECK-NEXT: %q.hity.hi = getelementptr i32* %q.hity.loty, i32 1 ; CHECK-NEXT: %q.hity.hity.loty = bitcast i32* %q.hity.hi to i16* ; CHECK-NEXT: %x.hi.hi.lo = load i16* %q.hity.hity.loty ; CHECK-NEXT: %x.hi.hi.lo.ext = zext i16 %x.hi.hi.lo to i32 ; CHECK-NEXT: %q.hity.hity.hi = getelementptr i16* %q.hity.hity.loty, i32 1 ; CHECK-NEXT: %q.hity.hity.hity = bitcast i16* %q.hity.hity.hi to i8* ; CHECK-NEXT: %x.hi.hi.hi = load i8* %q.hity.hity.hity ; CHECK-NEXT: %x.hi.hi.hi.ext = zext i8 %x.hi.hi.hi to i32 ; CHECK-NEXT: %x.hi.hi.hi.ext.sh = shl i32 %x.hi.hi.hi.ext, 16 ; CHECK-NEXT: %x.hi.hi = or i32 %x.hi.hi.lo.ext, %x.hi.hi.hi.ext.sh ; CHECK-NEXT: %x.hi.hi.ext = zext i32 %x.hi.hi to i64 ; CHECK-NEXT: %x.hi.hi.ext.sh = shl i64 %x.hi.hi.ext, 32 ; CHECK-NEXT: %x.hi = or i64 %x.hi.lo.ext, %x.hi.hi.ext.sh ; CHECK-NEXT: %x.hi.ext = zext i64 %x.hi to i128 ; CHECK-NEXT: %x.hi.ext.sh = shl i128 %x.hi.ext, 64 ; CHECK-NEXT: %x = or i128 %x.lo.ext, %x.hi.ext.sh ; CHECK-NEXT: %q.loty1 = bitcast i128* %q to i64* ; CHECK-NEXT: store i64 -5076944270305263616, i64* %q.loty1 ; CHECK-NEXT: %q.hi2 = getelementptr i64* %q.loty1, i32 1 ; CHECK-NEXT: %q.hity3.loty = bitcast i64* %q.hi2 to i32* ; CHECK-NEXT: store i32 1624466223, i32* %q.hity3.loty, align 1 ; CHECK-NEXT: %q.hity3.hi = getelementptr i32* %q.hity3.loty, i32 1 ; CHECK-NEXT: %q.hity3.hity.loty = bitcast i32* %q.hity3.hi to i16* ; CHECK-NEXT: store i16 3, i16* %q.hity3.hity.loty, align 1 ; CHECK-NEXT: %q.hity3.hity.hi = getelementptr i16* %q.hity3.hity.loty, i32 1 ; CHECK-NEXT: %q.hity3.hity.hity = bitcast i16* %q.hity3.hity.hi to i8* ; CHECK-NEXT: store i8 0, i8* %q.hity3.hity.hity ; CHECK-NEXT: %z = add i128 %x, 3 ; CHECK-NEXT: %y = trunc i128 %z to i32 ; CHECK-NEXT: ret i32 %y define i32 @bigger_integers(i8* %p) { %q = bitcast i8* %p to i120* %x = load i120* %q store i120 267650600228229401496703205376, i120* %q %z = add i120 %x, 3 %y = trunc i120 %z to i32 ret i32 %y }