Index: llvm/lib/CodeGen/TypePromotion.cpp =================================================================== --- llvm/lib/CodeGen/TypePromotion.cpp +++ llvm/lib/CodeGen/TypePromotion.cpp @@ -235,8 +235,6 @@ return true; else if (isa(V)) return true; - else if (isa(V)) - return true; else if (auto *Call = dyn_cast(V)) return Call->hasRetAttr(Attribute::AttrKind::ZExt); else if (auto *Trunc = dyn_cast(V)) @@ -724,8 +722,9 @@ case Instruction::Ret: case Instruction::Load: case Instruction::Trunc: - case Instruction::BitCast: return isSupportedType(I); + case Instruction::BitCast: + return I->getOperand(0)->getType() == I->getType(); case Instruction::ZExt: return isSupportedType(I->getOperand(0)); case Instruction::ICmp: Index: llvm/test/Transforms/TypePromotion/AArch64/bitcast.ll =================================================================== --- /dev/null +++ llvm/test/Transforms/TypePromotion/AArch64/bitcast.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py UTC_ARGS: --version 2 +; RUN: opt -mtriple=aarch64 -passes=typepromotion,verify,dce -S %s -o - | FileCheck %s + +target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128" + +define i1 @v8i8bitcast(<8 x i8> %a) { +; CHECK-LABEL: define i1 @v8i8bitcast +; CHECK-SAME: (<8 x i8> [[A:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[C:%.*]] = icmp slt <8 x i8> [[A]], zeroinitializer +; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i1> [[C]] to i8 +; CHECK-NEXT: [[N:%.*]] = icmp eq i8 [[TMP0]], 0 +; CHECK-NEXT: ret i1 [[N]] +; +entry: + %c = icmp slt <8 x i8> %a, zeroinitializer + %0 = bitcast <8 x i1> %c to i8 + %n = icmp eq i8 %0, 0 + ret i1 %n +} + +define i1 @halfbitcast() { +; CHECK-LABEL: define i1 @halfbitcast() { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast half 0xH8000 to i16 +; CHECK-NEXT: [[DOTNOT114:%.*]] = icmp eq i16 [[TMP0]], 0 +; CHECK-NEXT: ret i1 [[DOTNOT114]] +; +entry: + %0 = bitcast half 0xH8000 to i16 + %.not114 = icmp eq i16 %0, 0 + ret i1 %.not114 +} + +define i1 @v8i8constant(<8 x i1> %a) { +; CHECK-LABEL: define i1 @v8i8constant +; CHECK-SAME: (<8 x i1> [[A:%.*]]) { +; CHECK-NEXT: entry: +; CHECK-NEXT: [[TMP0:%.*]] = bitcast <8 x i1> to i8 +; CHECK-NEXT: [[DOTNOT114:%.*]] = icmp eq i8 [[TMP0]], 0 +; CHECK-NEXT: ret i1 [[DOTNOT114]] +; +entry: + %0 = bitcast <8 x i1> to i8 + %.not114 = icmp eq i8 %0, 0 + ret i1 %.not114 +} Index: llvm/test/Transforms/TypePromotion/ARM/casts.ll =================================================================== --- llvm/test/Transforms/TypePromotion/ARM/casts.ll +++ llvm/test/Transforms/TypePromotion/ARM/casts.ll @@ -248,10 +248,9 @@ ; CHECK-LABEL: @bitcast_i16( ; CHECK-NEXT: entry: ; CHECK-NEXT: [[TMP0:%.*]] = zext i16 [[ARG0:%.*]] to i32 -; CHECK-NEXT: [[CAST:%.*]] = bitcast i16 12345 to i16 -; CHECK-NEXT: [[TMP1:%.*]] = zext i16 [[CAST]] to i32 +; CHECK-NEXT: [[CAST:%.*]] = bitcast i32 12345 to i32 ; CHECK-NEXT: [[ADD:%.*]] = add nuw i32 [[TMP0]], 1 -; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[ADD]], [[TMP1]] +; CHECK-NEXT: [[CMP:%.*]] = icmp ule i32 [[ADD]], [[CAST]] ; CHECK-NEXT: [[RES:%.*]] = select i1 [[CMP]], i16 [[ARG1:%.*]], i16 32657 ; CHECK-NEXT: ret i16 [[RES]] ; @@ -1105,3 +1104,30 @@ %res = phi float [ 0.0, %entry ], [ %div, %if.end ] ret float %res } + +define i32 @bitcasted() { +; CHECK-LABEL: @bitcasted( +; CHECK-NEXT: entry: +; CHECK-NEXT: br label [[LOOP:%.*]] +; CHECK: loop: +; CHECK-NEXT: [[T157_PH:%.*]] = phi i32 [ 0, [[ENTRY:%.*]] ], [ [[T145_OLD:%.*]], [[LATCH:%.*]] ] +; CHECK-NEXT: [[EXT:%.*]] = zext i32 [[T157_PH]] to i64 +; CHECK-NEXT: br label [[LATCH]] +; CHECK: latch: +; CHECK-NEXT: [[T145_OLD]] = bitcast i32 8 to i32 +; CHECK-NEXT: [[T146_OLD:%.*]] = bitcast i32 [[T145_OLD]] to i32 +; CHECK-NEXT: br label [[LOOP]] +; +entry: + br label %loop + +loop: + %t157.ph = phi i32 [ 0, %entry ], [ %t145.old, %latch ] + %ext = zext i32 %t157.ph to i64 + br label %latch + +latch: + %t145.old = bitcast i32 8 to i32 + %t146.old = bitcast i32 %t145.old to i32 + br label %loop +}