Index: lib/Target/ARM/ARMCodeGenPrepare.cpp =================================================================== --- lib/Target/ARM/ARMCodeGenPrepare.cpp +++ lib/Target/ARM/ARMCodeGenPrepare.cpp @@ -175,13 +175,17 @@ } -static bool generateSignBits(Value *V) { +static bool GenerateSignBits(Value *V) { + if (auto *Arg = dyn_cast(V)) + return Arg->hasSExtAttr(); + if (!isa(V)) return false; unsigned Opc = cast(V)->getOpcode(); return Opc == Instruction::AShr || Opc == Instruction::SDiv || - Opc == Instruction::SRem; + Opc == Instruction::SRem || Opc == Instruction::SExt || + Opc == Instruction::SIToFP; } static bool EqualTypeSize(Value *V) { @@ -414,7 +418,7 @@ if (!isa(V)) return true; - if (generateSignBits(V)) + if (GenerateSignBits(V)) return false; return !isa(V); @@ -833,6 +837,11 @@ return EqualTypeSize(I->getOperand(0)); } + if (GenerateSignBits(V)) { + LLVM_DEBUG(dbgs() << "ARM CGP: No, instruction can generate sign bits.\n"); + return false; + } + // Memory instructions if (isa(V) || isa(V)) return true; @@ -849,9 +858,6 @@ isa(V)) return isSupportedType(V); - if (isa(V)) - return false; - if (auto *Cast = dyn_cast(V)) return isSupportedType(Cast) || isSupportedType(Cast->getOperand(0)); @@ -868,10 +874,6 @@ if (!isSupportedType(V)) return false; - if (generateSignBits(V)) { - LLVM_DEBUG(dbgs() << "ARM CGP: No, instruction can generate sign bits.\n"); - return false; - } return true; } Index: test/CodeGen/ARM/CGP/arm-cgp-casts.ll =================================================================== --- test/CodeGen/ARM/CGP/arm-cgp-casts.ll +++ test/CodeGen/ARM/CGP/arm-cgp-casts.ll @@ -643,3 +643,41 @@ %cond = phi i32 [ %phitmp, %cond.false ], [ 0, %entry ] ret i32 %cond } + +; CHECK-LABEL: test_i8_sitofp +; CHECK: uxtb +; CHECK: sxtb +define float @test_i8_sitofp(i8* %ptr, i8 %arg) { +entry: + %0 = load i8, i8* %ptr, align 1 + %cmp = icmp eq i8 %0, %arg + br i1 %cmp, label %exit, label %if.end + +if.end: + %conv = sitofp i8 %arg to float + %div = fdiv float %conv, 2.000000e+01 + br label %exit + +exit: + %res = phi float [ 0.0, %entry ], [ %div, %if.end ] + ret float %res +} + +; CHECK-LABEL: test_i16_sitofp +; CHECK: uxth +; CHECK: sxth +define float @test_i16_sitofp(i16* %ptr, i16 %arg) { +entry: + %0 = load i16, i16* %ptr, align 1 + %cmp = icmp eq i16 %0, %arg + br i1 %cmp, label %exit, label %if.end + +if.end: + %conv = sitofp i16 %arg to float + %div = fdiv float %conv, 2.000000e+01 + br label %exit + +exit: + %res = phi float [ 0.0, %entry ], [ %div, %if.end ] + ret float %res +} Index: test/CodeGen/ARM/CGP/arm-cgp-signed.ll =================================================================== --- test/CodeGen/ARM/CGP/arm-cgp-signed.ll +++ test/CodeGen/ARM/CGP/arm-cgp-signed.ll @@ -43,3 +43,28 @@ ret i16 %conv } +; CHECK-LABEL: test_signext_b +; CHECK: ldrb [[LDR:r[0-9]+]], [r0] +; CHECK: sxtb [[SXT:r[0-9]+]], [[LDR]] +; CHECK: cm{{.*}} [[SXT]] +define i32 @test_signext_b(i8* %ptr, i8 signext %arg) { +entry: + %0 = load i8, i8* %ptr, align 1 + %1 = add nuw nsw i8 %0, %arg + %cmp = icmp ult i8 %1, 128 + %res = select i1 %cmp, i32 42, i32 20894 + ret i32 %res +} + +; CHECK-LABEL: test_signext_h +; CHECK: ldrh [[LDR:r[0-9]+]], [r0] +; CHECK: sxth [[SXT:r[0-9]+]], [[LDR]] +; CHECK: cm{{.*}} [[SXT]] +define i32 @test_signext_h(i16* %ptr, i16 signext %arg) { +entry: + %0 = load i16, i16* %ptr, align 1 + %1 = add nuw nsw i16 %0, %arg + %cmp = icmp ult i16 %1, 32768 + %res = select i1 %cmp, i32 42, i32 20894 + ret i32 %res +}