1; This is distilled from a real function that led to a bug in the 2; address mode optimization code. It followed assignment chains 3; through non-SSA temporaries created from Phi instruction lowering. 4; 5; This test depends to some degree on the stability of "--verbose 6; addropt" output format. 7 8; REQUIRES: target_X8632 9; REQUIRES: allow_dump 10; RUN: %p2i -i %s --args -O2 --verbose addropt \ 11; RUN: -allow-externally-defined-symbols | FileCheck %s 12 13declare i32 @_calloc_r(i32, i32, i32) 14 15define internal i32 @_Balloc(i32 %ptr, i32 %k) { 16entry: 17 %gep = add i32 %ptr, 76 18 %gep.asptr = inttoptr i32 %gep to i32* 19 %0 = load i32, i32* %gep.asptr, align 1 20 %cmp = icmp eq i32 %0, 0 21 br i1 %cmp, label %if.then, label %if.end5 22 23if.then: ; preds = %entry 24 %call = tail call i32 @_calloc_r(i32 %ptr, i32 4, i32 33) 25 %gep.asptr2 = inttoptr i32 %gep to i32* 26 store i32 %call, i32* %gep.asptr2, align 1 27 %cmp3 = icmp eq i32 %call, 0 28 br i1 %cmp3, label %return, label %if.end5 29 30if.end5: ; preds = %if.then, %entry 31 %1 = phi i32 [ %call, %if.then ], [ %0, %entry ] 32 %gep_array = mul i32 %k, 4 33 %gep2 = add i32 %1, %gep_array 34 %gep2.asptr = inttoptr i32 %gep2 to i32* 35 %2 = load i32, i32* %gep2.asptr, align 1 36; The above load instruction is a good target for address mode 37; optimization. Correct analysis would lead to dump output like: 38; Starting computeAddressOpt for instruction: 39; [ 15] %__13 = load i32, i32* %gep2.asptr, align 1 40; Instruction: [ 14] %gep2.asptr = i32 %gep2 41; results in Base=%gep2, Index=<null>, Shift=0, Offset=0 42; Instruction: [ 13] %gep2 = add i32 %__9, %gep_array 43; results in Base=%__9, Index=%gep_array, Shift=0, Offset=0 44; Instruction: [ 18] %__9 = i32 %__9_phi 45; results in Base=%__9_phi, Index=%gep_array, Shift=0, Offset=0 46; Instruction: [ 12] %gep_array = mul i32 %k, 4 47; results in Base=%__9_phi, Index=%k, Shift=2, Offset=0 48; 49; Incorrect, overly-aggressive analysis would lead to output like: 50; Starting computeAddressOpt for instruction: 51; [ 15] %__13 = load i32, i32* %gep2.asptr, align 1 52; Instruction: [ 14] %gep2.asptr = i32 %gep2 53; results in Base=%gep2, Index=<null>, Shift=0, Offset=0 54; Instruction: [ 13] %gep2 = add i32 %__9, %gep_array 55; results in Base=%__9, Index=%gep_array, Shift=0, Offset=0 56; Instruction: [ 18] %__9 = i32 %__9_phi 57; results in Base=%__9_phi, Index=%gep_array, Shift=0, Offset=0 58; Instruction: [ 19] %__9_phi = i32 %__4 59; results in Base=%__4, Index=%gep_array, Shift=0, Offset=0 60; Instruction: [ 12] %gep_array = mul i32 %k, 4 61; results in Base=%__4, Index=%k, Shift=2, Offset=0 62; 63; CHECK-NOT: results in Base=%__4, 64; 65 ret i32 %2 66 67return: ; preds = %if.then 68 ret i32 0 69} 70