+
+; PR12514
+define i1 @test67(i1 %a, i32 %b) {
+ %tmp2 = zext i1 %a to i32
+ %conv6 = xor i32 %tmp2, 1
+ %and = and i32 %b, %conv6
+ %sext = shl nuw nsw i32 %and, 24
+ %neg.i = xor i32 %sext, -16777216
+ %conv.i.i = ashr exact i32 %neg.i, 24
+ %trunc = trunc i32 %conv.i.i to i8
+ %tobool.i = icmp eq i8 %trunc, 0
+ ret i1 %tobool.i
+; CHECK-LABEL: @test67(
+; CHECK: ret i1 false
+}
+
+%s = type { i32, i32, i32 }
+
+define %s @test68(%s *%p, i64 %i) {
+; CHECK-LABEL: @test68(
+ %o = mul i64 %i, 12
+ %q = bitcast %s* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o
+; CHECK-NEXT: getelementptr %s*
+ %r = bitcast i8* %pp to %s*
+ %l = load %s* %r
+; CHECK-NEXT: load %s*
+ ret %s %l
+; CHECK-NEXT: ret %s
+}
+
+; addrspacecasts should be eliminated.
+define %s @test68_addrspacecast(%s* %p, i64 %i) {
+; CHECK-LABEL: @test68_addrspacecast(
+; CHECK-NEXT: getelementptr %s*
+; CHECK-NEXT: load %s*
+; CHECK-NEXT: ret %s
+ %o = mul i64 %i, 12
+ %q = addrspacecast %s* %p to i8 addrspace(2)*
+ %pp = getelementptr inbounds i8 addrspace(2)* %q, i64 %o
+ %r = addrspacecast i8 addrspace(2)* %pp to %s*
+ %l = load %s* %r
+ ret %s %l
+}
+
+define %s @test68_addrspacecast_2(%s* %p, i64 %i) {
+; CHECK-LABEL: @test68_addrspacecast_2(
+; CHECK-NEXT: getelementptr %s* %p
+; CHECK-NEXT: addrspacecast
+; CHECK-NEXT: load %s addrspace(1)*
+; CHECK-NEXT: ret %s
+ %o = mul i64 %i, 12
+ %q = addrspacecast %s* %p to i8 addrspace(2)*
+ %pp = getelementptr inbounds i8 addrspace(2)* %q, i64 %o
+ %r = addrspacecast i8 addrspace(2)* %pp to %s addrspace(1)*
+ %l = load %s addrspace(1)* %r
+ ret %s %l
+}
+
+define %s @test68_as1(%s addrspace(1)* %p, i32 %i) {
+; CHECK-LABEL: @test68_as1(
+ %o = mul i32 %i, 12
+ %q = bitcast %s addrspace(1)* %p to i8 addrspace(1)*
+ %pp = getelementptr inbounds i8 addrspace(1)* %q, i32 %o
+; CHECK-NEXT: getelementptr %s addrspace(1)*
+ %r = bitcast i8 addrspace(1)* %pp to %s addrspace(1)*
+ %l = load %s addrspace(1)* %r
+; CHECK-NEXT: load %s addrspace(1)*
+ ret %s %l
+; CHECK-NEXT: ret %s
+}
+
+define double @test69(double *%p, i64 %i) {
+; CHECK-LABEL: @test69(
+ %o = shl nsw i64 %i, 3
+ %q = bitcast double* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o
+; CHECK-NEXT: getelementptr inbounds double*
+ %r = bitcast i8* %pp to double*
+ %l = load double* %r
+; CHECK-NEXT: load double*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define %s @test70(%s *%p, i64 %i) {
+; CHECK-LABEL: @test70(
+ %o = mul nsw i64 %i, 36
+; CHECK-NEXT: mul nsw i64 %i, 3
+ %q = bitcast %s* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o
+; CHECK-NEXT: getelementptr inbounds %s*
+ %r = bitcast i8* %pp to %s*
+ %l = load %s* %r
+; CHECK-NEXT: load %s*
+ ret %s %l
+; CHECK-NEXT: ret %s
+}
+
+define double @test71(double *%p, i64 %i) {
+; CHECK-LABEL: @test71(
+ %o = shl i64 %i, 5
+; CHECK-NEXT: shl i64 %i, 2
+ %q = bitcast double* %p to i8*
+ %pp = getelementptr i8* %q, i64 %o
+; CHECK-NEXT: getelementptr double*
+ %r = bitcast i8* %pp to double*
+ %l = load double* %r
+; CHECK-NEXT: load double*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define double @test72(double *%p, i32 %i) {
+; CHECK-LABEL: @test72(
+ %so = shl nsw i32 %i, 3
+ %o = sext i32 %so to i64
+; CHECK-NEXT: sext i32 %i to i64
+ %q = bitcast double* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o
+; CHECK-NEXT: getelementptr inbounds double*
+ %r = bitcast i8* %pp to double*
+ %l = load double* %r
+; CHECK-NEXT: load double*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define double @test73(double *%p, i128 %i) {
+; CHECK-LABEL: @test73(
+ %lo = shl nsw i128 %i, 3
+ %o = trunc i128 %lo to i64
+; CHECK-NEXT: trunc i128 %i to i64
+ %q = bitcast double* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o
+; CHECK-NEXT: getelementptr double*
+ %r = bitcast i8* %pp to double*
+ %l = load double* %r
+; CHECK-NEXT: load double*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define double @test74(double *%p, i64 %i) {
+; CHECK-LABEL: @test74(
+ %q = bitcast double* %p to i64*
+ %pp = getelementptr inbounds i64* %q, i64 %i
+; CHECK-NEXT: getelementptr inbounds double*
+ %r = bitcast i64* %pp to double*
+ %l = load double* %r
+; CHECK-NEXT: load double*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define i32* @test75(i32* %p, i32 %x) {
+; CHECK-LABEL: @test75(
+ %y = shl i32 %x, 3
+; CHECK-NEXT: shl i32 %x, 3
+ %z = sext i32 %y to i64
+; CHECK-NEXT: sext i32 %y to i64
+ %q = bitcast i32* %p to i8*
+ %r = getelementptr i8* %q, i64 %z
+ %s = bitcast i8* %r to i32*
+ ret i32* %s
+}
+
+define %s @test76(%s *%p, i64 %i, i64 %j) {
+; CHECK-LABEL: @test76(
+ %o = mul i64 %i, 12
+ %o2 = mul nsw i64 %o, %j
+; CHECK-NEXT: %o2 = mul i64 %i, %j
+ %q = bitcast %s* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o2
+; CHECK-NEXT: getelementptr %s* %p, i64 %o2
+ %r = bitcast i8* %pp to %s*
+ %l = load %s* %r
+; CHECK-NEXT: load %s*
+ ret %s %l
+; CHECK-NEXT: ret %s
+}
+
+define %s @test77(%s *%p, i64 %i, i64 %j) {
+; CHECK-LABEL: @test77(
+ %o = mul nsw i64 %i, 36
+ %o2 = mul nsw i64 %o, %j
+; CHECK-NEXT: %o = mul nsw i64 %i, 3
+; CHECK-NEXT: %o2 = mul nsw i64 %o, %j
+ %q = bitcast %s* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %o2
+; CHECK-NEXT: getelementptr inbounds %s* %p, i64 %o2
+ %r = bitcast i8* %pp to %s*
+ %l = load %s* %r
+; CHECK-NEXT: load %s*
+ ret %s %l
+; CHECK-NEXT: ret %s
+}
+
+define %s @test78(%s *%p, i64 %i, i64 %j, i32 %k, i32 %l, i128 %m, i128 %n) {
+; CHECK-LABEL: @test78(
+ %a = mul nsw i32 %k, 36
+; CHECK-NEXT: mul nsw i32 %k, 3
+ %b = mul nsw i32 %a, %l
+; CHECK-NEXT: mul nsw i32 %a, %l
+ %c = sext i32 %b to i128
+; CHECK-NEXT: sext i32 %b to i128
+ %d = mul nsw i128 %c, %m
+; CHECK-NEXT: mul nsw i128 %c, %m
+ %e = mul i128 %d, %n
+; CHECK-NEXT: mul i128 %d, %n
+ %f = trunc i128 %e to i64
+; CHECK-NEXT: trunc i128 %e to i64
+ %g = mul nsw i64 %f, %i
+; CHECK-NEXT: mul i64 %f, %i
+ %h = mul nsw i64 %g, %j
+; CHECK-NEXT: mul i64 %g, %j
+ %q = bitcast %s* %p to i8*
+ %pp = getelementptr inbounds i8* %q, i64 %h
+; CHECK-NEXT: getelementptr %s* %p, i64 %h
+ %r = bitcast i8* %pp to %s*
+ %load = load %s* %r
+; CHECK-NEXT: load %s*
+ ret %s %load
+; CHECK-NEXT: ret %s
+}
+
+define %s @test79(%s *%p, i64 %i, i32 %j) {
+; CHECK-LABEL: @test79(
+ %a = mul nsw i64 %i, 36
+; CHECK: mul nsw i64 %i, 36
+ %b = trunc i64 %a to i32
+ %c = mul i32 %b, %j
+ %q = bitcast %s* %p to i8*
+; CHECK: bitcast
+ %pp = getelementptr inbounds i8* %q, i32 %c
+ %r = bitcast i8* %pp to %s*
+ %l = load %s* %r
+ ret %s %l
+}
+
+define double @test80([100 x double]* %p, i32 %i) {
+; CHECK-LABEL: @test80(
+ %tmp = shl nsw i32 %i, 3
+; CHECK-NEXT: sext i32 %i to i64
+ %q = bitcast [100 x double]* %p to i8*
+ %pp = getelementptr i8* %q, i32 %tmp
+; CHECK-NEXT: getelementptr [100 x double]*
+ %r = bitcast i8* %pp to double*
+ %l = load double* %r
+; CHECK-NEXT: load double*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define double @test80_addrspacecast([100 x double] addrspace(1)* %p, i32 %i) {
+; CHECK-LABEL: @test80_addrspacecast(
+; CHECK-NEXT: getelementptr [100 x double] addrspace(1)* %p
+; CHECK-NEXT: load double addrspace(1)*
+; CHECK-NEXT: ret double
+ %tmp = shl nsw i32 %i, 3
+ %q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
+ %pp = getelementptr i8 addrspace(2)* %q, i32 %tmp
+ %r = addrspacecast i8 addrspace(2)* %pp to double addrspace(1)*
+ %l = load double addrspace(1)* %r
+ ret double %l
+}
+
+define double @test80_addrspacecast_2([100 x double] addrspace(1)* %p, i32 %i) {
+; CHECK-LABEL: @test80_addrspacecast_2(
+; CHECK-NEXT: getelementptr [100 x double] addrspace(1)*
+; CHECK-NEXT: addrspacecast double addrspace(1)*
+; CHECK-NEXT: load double addrspace(3)*
+; CHECK-NEXT: ret double
+ %tmp = shl nsw i32 %i, 3
+ %q = addrspacecast [100 x double] addrspace(1)* %p to i8 addrspace(2)*
+ %pp = getelementptr i8 addrspace(2)* %q, i32 %tmp
+ %r = addrspacecast i8 addrspace(2)* %pp to double addrspace(3)*
+ %l = load double addrspace(3)* %r
+ ret double %l
+}
+
+define double @test80_as1([100 x double] addrspace(1)* %p, i16 %i) {
+; CHECK-LABEL: @test80_as1(
+ %tmp = shl nsw i16 %i, 3
+; CHECK-NEXT: sext i16 %i to i32
+ %q = bitcast [100 x double] addrspace(1)* %p to i8 addrspace(1)*
+ %pp = getelementptr i8 addrspace(1)* %q, i16 %tmp
+; CHECK-NEXT: getelementptr [100 x double] addrspace(1)*
+ %r = bitcast i8 addrspace(1)* %pp to double addrspace(1)*
+ %l = load double addrspace(1)* %r
+; CHECK-NEXT: load double addrspace(1)*
+ ret double %l
+; CHECK-NEXT: ret double
+}
+
+define double @test81(double *%p, float %f) {
+ %i = fptosi float %f to i64
+ %q = bitcast double* %p to i8*
+ %pp = getelementptr i8* %q, i64 %i
+ %r = bitcast i8* %pp to double*
+ %l = load double* %r
+ ret double %l
+}
+
+define i64 @test82(i64 %A) nounwind {
+ %B = trunc i64 %A to i32
+ %C = lshr i32 %B, 8
+ %D = shl i32 %C, 9
+ %E = zext i32 %D to i64
+ ret i64 %E
+
+; CHECK-LABEL: @test82(
+; CHECK-NEXT: [[REG:%[0-9]*]] = shl i64 %A, 1
+; CHECK-NEXT: %E = and i64 [[REG]], 4294966784
+; CHECK-NEXT: ret i64 %E
+}
+
+; PR15959
+define i64 @test83(i16 %a, i64 %k) {
+ %conv = sext i16 %a to i32
+ %sub = add nsw i64 %k, -1
+ %sh_prom = trunc i64 %sub to i32
+ %shl = shl i32 %conv, %sh_prom
+ %sh_prom1 = zext i32 %shl to i64
+ ret i64 %sh_prom1
+
+; CHECK-LABEL: @test83(
+; CHECK: %sub = add i64 %k, 4294967295
+; CHECK: %sh_prom = trunc i64 %sub to i32
+; CHECK: %shl = shl i32 %conv, %sh_prom
+}
+
+define i8 @test84(i32 %a) {
+ %add = add nsw i32 %a, -16777216
+ %shr = lshr exact i32 %add, 23
+ %trunc = trunc i32 %shr to i8
+ ret i8 %trunc
+
+; CHECK-LABEL: @test84(
+; CHECK: [[ADD:%.*]] = add i32 %a, 2130706432
+; CHECK: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
+; CHECK: [[CST:%.*]] = trunc i32 [[SHR]] to i8
+}
+
+define i8 @test85(i32 %a) {
+ %add = add nuw i32 %a, -16777216
+ %shr = lshr exact i32 %add, 23
+ %trunc = trunc i32 %shr to i8
+ ret i8 %trunc
+
+; CHECK-LABEL: @test85(
+; CHECK: [[ADD:%.*]] = add i32 %a, 2130706432
+; CHECK: [[SHR:%.*]] = lshr exact i32 [[ADD]], 23
+; CHECK: [[CST:%.*]] = trunc i32 [[SHR]] to i8
+}
+
+; Overflow on a float to int or int to float conversion is undefined (PR21130).
+
+define i8 @overflow_fptosi() {
+ %i = fptosi double 1.56e+02 to i8
+ ret i8 %i
+; CHECK-LABEL: @overflow_fptosi(
+; CHECK-NEXT: ret i8 undef
+}
+
+define i8 @overflow_fptoui() {
+ %i = fptoui double 2.56e+02 to i8
+ ret i8 %i
+; CHECK-LABEL: @overflow_fptoui(
+; CHECK-NEXT: ret i8 undef
+}
+
+; The maximum float is approximately 2 ** 128 which is 3.4E38.
+; The constant below is 4E38. Use a 130 bit integer to hold that
+; number; 129-bits for the value + 1 bit for the sign.
+define float @overflow_uitofp() {
+ %i = uitofp i130 400000000000000000000000000000000000000 to float
+ ret float %i
+; CHECK-LABEL: @overflow_uitofp(
+; CHECK-NEXT: ret float undef
+}
+
+define float @overflow_sitofp() {
+ %i = sitofp i130 400000000000000000000000000000000000000 to float
+ ret float %i
+; CHECK-LABEL: @overflow_sitofp(
+; CHECK-NEXT: ret float undef
+}
+
+define i32 @PR21388(i32* %v) {
+ %icmp = icmp slt i32* %v, null
+ %sext = sext i1 %icmp to i32
+ ret i32 %sext
+; CHECK-LABEL: @PR21388(
+; CHECK-NEXT: %[[icmp:.*]] = icmp slt i32* %v, null
+; CHECK-NEXT: %[[sext:.*]] = sext i1 %[[icmp]] to i32
+; CHECK-NEXT: ret i32 %[[sext]]
+}