diff options
-rw-r--r-- | lib/Target/ARM/ARMLoadStoreOptimizer.cpp | 4 | ||||
-rw-r--r-- | test/CodeGen/Thumb2/crash.ll | 15 |
2 files changed, 19 insertions, 0 deletions
diff --git a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp index f75ac90b22..5770f7739a 100644 --- a/lib/Target/ARM/ARMLoadStoreOptimizer.cpp +++ b/lib/Target/ARM/ARMLoadStoreOptimizer.cpp @@ -1184,6 +1184,10 @@ bool ARMLoadStoreOpt::FixInvalidRegPairOp(MachineBasicBlock &MBB, EvenDeadKill = false; OddDeadKill = true; } + // Never kill the base register in the first instruction. + // <rdar://problem/11101911> + if (EvenReg == BaseReg) + EvenDeadKill = false; InsertLDR_STR(MBB, MBBI, OffImm, isLd, dl, NewOpc, EvenReg, EvenDeadKill, EvenUndef, BaseReg, false, BaseUndef, false, OffUndef, diff --git a/test/CodeGen/Thumb2/crash.ll b/test/CodeGen/Thumb2/crash.ll index 52893af937..cb4d08058f 100644 --- a/test/CodeGen/Thumb2/crash.ll +++ b/test/CodeGen/Thumb2/crash.ll @@ -61,3 +61,18 @@ entry: declare <4 x float> @llvm.arm.neon.vld1.v4f32(i8*, i32) nounwind readonly declare void @llvm.arm.neon.vst1.v4f32(i8*, <4 x float>, i32) nounwind + +; <rdar://problem/11101911> +; When an strd is expanded into two str instructions, make sure the first str +; doesn't kill the base register. This can happen if the base register is the +; same as the data register. +%class = type { i8*, %class*, i32 } +define void @f11101911(%class* %this, i32 %num) ssp align 2 { +entry: + %p1 = getelementptr inbounds %class* %this, i32 0, i32 1 + %p2 = getelementptr inbounds %class* %this, i32 0, i32 2 + tail call void asm sideeffect "", "~{r1},~{r3},~{r5},~{r11},~{r13}"() nounwind + store %class* %this, %class** %p1, align 4 + store i32 %num, i32* %p2, align 4 + ret void +} |