; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -mtriple=aarch64-linux-gnu -type-promotion -verify -S %s -o - | FileCheck %s target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" %struct.bar = type { %struct.foo } %struct.foo = type { %struct.wobble* } %struct.wobble = type { %struct.zot* } %struct.zot = type <{ %struct.wobble, %struct.zot*, %struct.wobble*, i8, [7 x i8] }> @global = external global %struct.bar, align 8 define i64 @zext_trunc_i8_i16_i32_i64() { ; CHECK-LABEL: @zext_trunc_i8_i16_i32_i64( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[VAR:%.*]] = load %struct.wobble*, %struct.wobble** getelementptr inbounds ([[STRUCT_BAR:%.*]], %struct.bar* @global, i64 0, i32 0, i32 0), align 8 ; CHECK-NEXT: br label [[PREHEADER:%.*]] ; CHECK: preheader: ; CHECK-NEXT: br label [[HEADER:%.*]] ; CHECK: header: ; CHECK-NEXT: [[VAR4:%.*]] = phi i64 [ [[VAR30:%.*]], [[LATCH:%.*]] ], [ 0, [[PREHEADER]] ] ; CHECK-NEXT: [[VAR5:%.*]] = phi %struct.wobble* [ [[VAR38:%.*]], [[LATCH]] ], [ [[VAR]], [[PREHEADER]] ] ; CHECK-NEXT: [[VAR6:%.*]] = phi i32 [ [[VAR21:%.*]], [[LATCH]] ], [ 0, [[PREHEADER]] ] ; CHECK-NEXT: br label [[MIDBLOCK:%.*]] ; CHECK: midblock: ; CHECK-NEXT: [[VAR15:%.*]] = getelementptr inbounds [[STRUCT_WOBBLE:%.*]], %struct.wobble* [[VAR5]], i64 9 ; CHECK-NEXT: [[VAR16:%.*]] = bitcast %struct.wobble* [[VAR15]] to i16* ; CHECK-NEXT: [[VAR17:%.*]] = load i16, i16* [[VAR16]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[VAR17]] to i32 ; CHECK-NEXT: [[VAR18:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: [[VAR19:%.*]] = lshr i32 [[TMP0]], 8 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[VAR19]], 255 ; CHECK-NEXT: [[VAR21]] = select i1 [[VAR18]], i32 [[VAR6]], i32 [[TMP1]] ; CHECK-NEXT: [[VAR23:%.*]] = shl nuw i32 [[VAR21]], 8 ; CHECK-NEXT: [[VAR24:%.*]] = and i32 [[TMP0]], 255 ; CHECK-NEXT: [[VAR25:%.*]] = or i32 [[VAR23]], [[VAR24]] ; CHECK-NEXT: [[VAR26:%.*]] = select i1 [[VAR18]], i64 0, i64 65536 ; CHECK-NEXT: [[VAR27:%.*]] = zext i32 [[VAR25]] to i64 ; CHECK-NEXT: [[VAR28:%.*]] = and i64 [[VAR4]], -4294967296 ; CHECK-NEXT: [[VAR29:%.*]] = or i64 [[VAR26]], [[VAR28]] ; CHECK-NEXT: [[VAR30]] = or i64 [[VAR29]], [[VAR27]] ; CHECK-NEXT: br label [[LATCH]] ; CHECK: latch: ; CHECK-NEXT: [[VAR34:%.*]] = getelementptr inbounds [[STRUCT_WOBBLE]], %struct.wobble* [[VAR5]], i64 1, i32 0 ; CHECK-NEXT: [[VAR35:%.*]] = load %struct.zot*, %struct.zot** [[VAR34]], align 8 ; CHECK-NEXT: [[VAR36:%.*]] = icmp eq %struct.zot* [[VAR35]], null ; CHECK-NEXT: [[VAR37:%.*]] = getelementptr inbounds [[STRUCT_ZOT:%.*]], %struct.zot* [[VAR35]], i64 0, i32 2 ; CHECK-NEXT: [[VAR38]] = load %struct.wobble*, %struct.wobble** [[VAR37]], align 8 ; CHECK-NEXT: br i1 [[VAR36]], label [[EXIT:%.*]], label [[HEADER]] ; CHECK: exit: ; CHECK-NEXT: ret i64 [[VAR30]] ; entry: %var = load %struct.wobble*, %struct.wobble** getelementptr inbounds (%struct.bar, %struct.bar* @global, i64 0, i32 0, i32 0), align 8 br label %preheader preheader: br label %header header: ; preds = %bb63, %bb %var4 = phi i64 [ %var30, %latch ], [ 0, %preheader ] %var5 = phi %struct.wobble* [ %var38, %latch ], [ %var, %preheader ] %var6 = phi i8 [ %var21, %latch ], [ 0, %preheader ] br label %midblock midblock: ; preds = %bb9 %var15 = getelementptr inbounds %struct.wobble, %struct.wobble* %var5, i64 9 %var16 = bitcast %struct.wobble* %var15 to i16* %var17 = load i16, i16* %var16, align 8 %var18 = icmp eq i16 %var17, 0 %var19 = lshr i16 %var17, 8 %var20 = trunc i16 %var19 to i8 %var21 = select i1 %var18, i8 %var6, i8 %var20 %var22 = zext i8 %var21 to i16 %var23 = shl nuw i16 %var22, 8 %var24 = and i16 %var17, 255 %var25 = or i16 %var23, %var24 %var26 = select i1 %var18, i64 0, i64 65536 %var27 = zext i16 %var25 to i64 %var28 = and i64 %var4, -4294967296 %var29 = or i64 %var26, %var28 %var30 = or i64 %var29, %var27 br label %latch latch: ; preds = %bb14, %bb9 %var34 = getelementptr inbounds %struct.wobble, %struct.wobble* %var5, i64 1, i32 0 %var35 = load %struct.zot*, %struct.zot** %var34, align 8 %var36 = icmp eq %struct.zot* %var35, null %var37 = getelementptr inbounds %struct.zot, %struct.zot* %var35, i64 0, i32 2 %var38 = load %struct.wobble*, %struct.wobble** %var37, align 8 br i1 %var36, label %exit, label %header exit: ret i64 %var30 } define i64 @with_undef() { ; CHECK-LABEL: @with_undef( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[VAR:%.*]] = load %struct.wobble*, %struct.wobble** getelementptr inbounds ([[STRUCT_BAR:%.*]], %struct.bar* @global, i64 0, i32 0, i32 0), align 8 ; CHECK-NEXT: br label [[PREHEADER:%.*]] ; CHECK: preheader: ; CHECK-NEXT: br label [[HEADER:%.*]] ; CHECK: header: ; CHECK-NEXT: [[VAR4:%.*]] = phi i64 [ [[VAR30:%.*]], [[LATCH:%.*]] ], [ undef, [[PREHEADER]] ] ; CHECK-NEXT: [[VAR5:%.*]] = phi %struct.wobble* [ [[VAR38:%.*]], [[LATCH]] ], [ [[VAR]], [[PREHEADER]] ] ; CHECK-NEXT: [[VAR6:%.*]] = phi i32 [ [[VAR21:%.*]], [[LATCH]] ], [ 0, [[PREHEADER]] ] ; CHECK-NEXT: br label [[MIDBLOCK:%.*]] ; CHECK: midblock: ; CHECK-NEXT: [[VAR15:%.*]] = getelementptr inbounds [[STRUCT_WOBBLE:%.*]], %struct.wobble* [[VAR5]], i64 9 ; CHECK-NEXT: [[VAR16:%.*]] = bitcast %struct.wobble* [[VAR15]] to i16* ; CHECK-NEXT: [[VAR17:%.*]] = load i16, i16* [[VAR16]], align 8 ; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[VAR17]] to i32 ; CHECK-NEXT: [[VAR18:%.*]] = icmp eq i32 [[TMP0]], 0 ; CHECK-NEXT: [[VAR19:%.*]] = lshr i32 [[TMP0]], 8 ; CHECK-NEXT: [[TMP1:%.*]] = and i32 [[VAR19]], 255 ; CHECK-NEXT: [[VAR21]] = select i1 [[VAR18]], i32 [[VAR6]], i32 [[TMP1]] ; CHECK-NEXT: [[VAR23:%.*]] = shl nuw i32 [[VAR21]], 8 ; CHECK-NEXT: [[VAR24:%.*]] = and i32 [[TMP0]], 255 ; CHECK-NEXT: [[VAR25:%.*]] = or i32 [[VAR23]], [[VAR24]] ; CHECK-NEXT: [[VAR26:%.*]] = select i1 [[VAR18]], i64 0, i64 65536 ; CHECK-NEXT: [[VAR27:%.*]] = zext i32 [[VAR25]] to i64 ; CHECK-NEXT: [[VAR28:%.*]] = and i64 [[VAR4]], -4294967296 ; CHECK-NEXT: [[VAR29:%.*]] = or i64 [[VAR26]], [[VAR28]] ; CHECK-NEXT: [[VAR30]] = or i64 [[VAR29]], [[VAR27]] ; CHECK-NEXT: br label [[LATCH]] ; CHECK: latch: ; CHECK-NEXT: [[VAR34:%.*]] = getelementptr inbounds [[STRUCT_WOBBLE]], %struct.wobble* [[VAR5]], i64 1, i32 0 ; CHECK-NEXT: [[VAR35:%.*]] = load %struct.zot*, %struct.zot** [[VAR34]], align 8 ; CHECK-NEXT: [[VAR36:%.*]] = icmp eq %struct.zot* [[VAR35]], null ; CHECK-NEXT: [[VAR37:%.*]] = getelementptr inbounds [[STRUCT_ZOT:%.*]], %struct.zot* [[VAR35]], i64 0, i32 2 ; CHECK-NEXT: [[VAR38]] = load %struct.wobble*, %struct.wobble** [[VAR37]], align 8 ; CHECK-NEXT: br i1 [[VAR36]], label [[EXIT:%.*]], label [[HEADER]] ; CHECK: exit: ; CHECK-NEXT: ret i64 [[VAR30]] ; entry: %var = load %struct.wobble*, %struct.wobble** getelementptr inbounds (%struct.bar, %struct.bar* @global, i64 0, i32 0, i32 0), align 8 br label %preheader preheader: br label %header header: ; preds = %bb63, %bb %var4 = phi i64 [ %var30, %latch ], [ undef, %preheader ] %var5 = phi %struct.wobble* [ %var38, %latch ], [ %var, %preheader ] %var6 = phi i8 [ %var21, %latch ], [ undef, %preheader ] br label %midblock midblock: ; preds = %bb9 %var15 = getelementptr inbounds %struct.wobble, %struct.wobble* %var5, i64 9 %var16 = bitcast %struct.wobble* %var15 to i16* %var17 = load i16, i16* %var16, align 8 %var18 = icmp eq i16 %var17, 0 %var19 = lshr i16 %var17, 8 %var20 = trunc i16 %var19 to i8 %var21 = select i1 %var18, i8 %var6, i8 %var20 %var22 = zext i8 %var21 to i16 %var23 = shl nuw i16 %var22, 8 %var24 = and i16 %var17, 255 %var25 = or i16 %var23, %var24 %var26 = select i1 %var18, i64 0, i64 65536 %var27 = zext i16 %var25 to i64 %var28 = and i64 %var4, -4294967296 %var29 = or i64 %var26, %var28 %var30 = or i64 %var29, %var27 br label %latch latch: ; preds = %bb14, %bb9 %var34 = getelementptr inbounds %struct.wobble, %struct.wobble* %var5, i64 1, i32 0 %var35 = load %struct.zot*, %struct.zot** %var34, align 8 %var36 = icmp eq %struct.zot* %var35, null %var37 = getelementptr inbounds %struct.zot, %struct.zot* %var35, i64 0, i32 2 %var38 = load %struct.wobble*, %struct.wobble** %var37, align 8 br i1 %var36, label %exit, label %header exit: ret i64 %var30 } ; Check the case don't crash due to zext source type bitwidth ; larger than dest type bitwidth. define i1 @pr58843(i8 %arg) { ; CHECK-LABEL: @pr58843( ; CHECK-NEXT: [[EXT1:%.*]] = zext i8 [[ARG:%.*]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[EXT1]], 7 ; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 ; CHECK-NEXT: [[CMP:%.*]] = icmp ne i32 [[TMP2]], 0 ; CHECK-NEXT: ret i1 [[CMP]] ; %ext1 = zext i8 %arg to i64 %trunc = trunc i64 %ext1 to i3 %ext2 = zext i3 %trunc to i8 %cmp = icmp ne i8 %ext2, 0 ret i1 %cmp } ; Check the case don't crash due to xor two op have different ; types define i1 @pr59554(i8 %arg) { ; CHECK-LABEL: @pr59554( ; CHECK-NEXT: [[ARG_EXT:%.*]] = zext i8 [[ARG:%.*]] to i64 ; CHECK-NEXT: [[TMP1:%.*]] = and i64 [[ARG_EXT]], 7 ; CHECK-NEXT: [[TMP2:%.*]] = trunc i64 [[TMP1]] to i32 ; CHECK-NEXT: [[SWITCH_TABLEIDX:%.*]] = xor i32 [[TMP2]], 1 ; CHECK-NEXT: [[SWITCH_LOBIT:%.*]] = icmp ne i32 [[TMP2]], 0 ; CHECK-NEXT: ret i1 [[SWITCH_LOBIT]] ; %arg.ext = zext i8 %arg to i64 %trunc = trunc i64 %arg.ext to i3 %switch.tableidx = xor i3 %trunc, 1 %switch.maskindex = zext i3 %trunc to i8 %switch.lobit = icmp ne i8 %switch.maskindex, 0 ret i1 %switch.lobit }